SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

japan.internet.com翻訳記事

Rubyが.NETプラットフォームにやってくる

.NETプログラマのためのRuby入門

  • X ポスト
  • このエントリーをはてなブックマークに追加

メタプログラミング

 Rubyにはプロパティはありませんが、メソッド呼び出しに(通常は)かっこが必要でないことを利用して、プロパティをシミュレートできます。また、Rubyでは=で終わるメソッドが特別に扱われ、セッターのように振る舞うことも利用する必要があります。

 例えば、人(Person)のクラスを次のように定義します。

irb(main):001:0> class Person
irb(main):002:1>   def age
irb(main):003:2>     @age
irb(main):004:2>   end
irb(main):005:1>   def age=(value)
irb(main):006:2>     @age = value
irb(main):007:2>   end
irb(main):008:1> end
=> nil

 こうすると、Personのインスタンスを使って、年齢(age)を人のプロパティのように扱うことができます。

irb(main):009:0> p = Person.new
=> #<Person:0x89c5678>
irb(main):010:0> p.age
=> nil
irb(main):011:0> p.age = 42
=> 42
irb(main):012:0> p.age
=> 42

 ageのデフォルト値をnil以外にしたい場合は、initializeメソッドで設定できます。

 このコードは非常に定型的な感じがします。これがC#などの言語であれば、おそらくVisual Studioのスニペットのようなものを使うか、静的コード生成でプロパティのリーダーとライターを自動的に生成したくなるでしょう。

 しかしRubyでは、メタプログラミングを使って、ほんのわずかな労力でそうしたものを作成できます。理想は次のような記述ができることです。

class Person
  prop :age
end

 Objectのクラス(静的)メソッドを定義し、自分のクラスを定義するときにそれを利用できるようにします。また、ここで初めて目にするclass_evalというメソッドも使います。

irb(main):001:0> class Object
irb(main):002:1>   def self.prop *names
irb(main):003:2>     names.each { |name|
irb(main):004:3*       self.class_eval "
irb(main):005:3"         def #{name}
irb(main):006:3"           @#{name}
irb(main):007:3"         end"
irb(main):008:3>       self.class_eval "
irb(main):009:3"         def #{name}=(value)
irb(main):010:3"           @#{name} = value
irb(main):011:3"         end"
irb(main):012:3>     }
irb(main):013:2>     nil
irb(main):014:2>   end
irb(main):015:1> end
=> nil

 ここで使われているclass_evalメソッドが、最終的にメソッドを作成することになります。このメソッドは、クラス自体のコンテキストで行ったかのように文字列を評価します。そのため、最初からクラスの中に記述してきたかのようにメソッドを記述できます。

 propメソッドに渡されるそれぞれの名前は、新しいクラスにゲッターとセッターの2つのメソッドを追加します。できあがった文字列では、#{name}が、propに渡した名前に置き換わります。

 これでpropをクラス定義で使うことができます。

irb(main):016:0> class Person
irb(main):017:1>   prop :age, :name
irb(main):018:1>
irb(main):019:1*   def initialize(age, name)
irb(main):020:2>     @age = age
irb(main):021:2>     @name = name
irb(main):022:2>   end
irb(main):023:1> end
=> nil
irb(main):024:0> p = Person.new(36, "Brad")
=> #<Person:0x89c0768 @age=36, @name="Brad">
irb(main):025:0> p.age
=> 36
irb(main):026:0> p.name
=> "Brad"

 このような機能を自在に使いこなすことで、作業の大部分をこうしたメタプログラミングの仕掛けに任せて、はるかに高いレベルでクラスをすばやく作成できます。エディタのスニペットやコンパイル時のコード生成に頼る必要はありません。

次のステップ

 本稿では、Rubyで利用できる機能のほんのうわべをなでたにすぎません。今からRubyを習得すれば、.NETやSilverlightでRubyを利用できるようになったときの備えになります。これほど強力な動的言語を身に付けることは、プログラマにとって大きな強みになります。しかし、もっと重要なのは、それが問題と解決策を新しい方法で考えるためのきっかけになることです。

 Rubyについてさらに学習したい場合は、表紙の絵から「つるはし本」とも呼ばれる、David Thomas/Andrew Hunt共著『Programming Ruby: The Pragmatic Programmer's Guide』(Addison-Wesley Professional)【邦訳:『プログラミングRuby - 達人プログラマーガイド』(ピアソンエデュケーション)】を強くお勧めします。

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
japan.internet.com翻訳記事連載記事一覧

もっと読む

この記事の著者

japan.internet.com(ジャパンインターネットコム)

japan.internet.com は、1999年9月にオープンした、日本初のネットビジネス専門ニュースサイト。月間2億以上のページビューを誇る米国 Jupitermedia Corporation (Nasdaq: JUPM) のニュースサイト internet.comEarthWeb.com からの最新記事を日本語に翻訳して掲載するとともに、日本独自のネットビジネス関連記事やレポートを配信。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

Brad Wilson(Brad Wilson)

ASP.NETチームのソフトウェア開発者としてMicrosoftに3年以上在籍。開発者としての経歴は15年を超える。.NET 2.0のテスト用開発フレームワークであるxUnit.netの共同製作者の1人である。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/3405 2009/01/14 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング