SHOEISHA iD

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

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

japan.internet.com翻訳記事

Java開発者のためのRubyガイド

Javaと比較したRubyの文法

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

既存のクラスの編集

 Rubyの多様性のポイントは、Rubyのすべてのクラスをメソッドとデータを追加して拡張できるという点です。私はよく、コアRubyクラスのオリジナルのソースコードを拡張するのではなく、自分が開発しているアプリケーション内でクラスを拡張するという方法をとります。JavaやC++開発者にとっては奇妙に思えるかもしれませんが、このテクニックを使うと、プロジェクトのリソースを1か所で管理でき、オリジナルのクラスを「膨張」させることなく多くの開発者がアプリケーション固有の機能を追加できるようになります。Javaプログラマの立場で、Javaのルールによる制約を考えてみてください。Javaでは既存のクラスに機能やデータを追加する場合、サブクラスを作成する必要があります。

 次のリストは、Stringクラスにstemメソッドを追加する方法を示しています。

begin
  # stem is undefined at this point
  puts "The trips will be longer in the future".downcase.stem 
rescue
    puts 'Error:' + $!
end

require "rubygems"
require_gem 'stemmer'

class String # you will extend the String class
  include Stemmable # add methods and data defined in module Stemmable
end

puts "The trips will be longer in the future".downcase.stem

 また、自分のアプリケーション内で、既存のクラスにメソッドや新しいクラスインスタンス変数を追加できると便利なことが分かります。

 次の節では、Rubyの強力な柔軟性を証明するもう1つの例である「ダックタイピング」(duck typing)について説明します。

Rubyのダックタイピング

 Javaでは、オブジェクトのクラス階層で(publicやpackageなどの可視性を指定して)定義したオブジェクトのメソッドしか呼び出せません。例えば、あるオブジェクトのコレクションがあり、そのコレクション内の各要素に対して、1つ以上のメソッドを呼び出す処理を繰り返す場合を考えてみましょう。Javaでこのような処理を行う場合、対象となるオブジェクトは同じクラス階層に属しているか、呼び出すメソッドを定義しているインターフェイスを実装している必要があります。

 話の流れから予想はついていると思いますが、RubyはJavaよりもはるかに柔軟です。Rubyのランタイムのメソッド呼び出しスキームでは、固有のデータ型やクラスは必要ありません。次のように、objオブジェクトのfooメソッドを呼び出し、この最初のメソッド呼び出しによって取得したオブジェクトからbarメソッドを呼び出すとします(この例は2つの同じ呼び出しを示しています。メソッドに引数がない場合、()は省略できます)。

obj.foo.bar
obj.foo().bar()

 obj.fooを呼び出した結果はオブジェクトになります。そして、この新しいオブジェクトのクラスが何であろうと、そのオブジェクトのbarメソッドを呼び出すことになります。

 もう1つの例として、コレクション内の各オブジェクトからnameというメソッドを呼び出すことを考えます。このコレクション内の1つの要素が、何らかの理由で、nameメソッドが定義されていないMyClass2クラスのインスタンスになったとしましょう。その場合、このオブジェクトからnameメソッドを最初に呼び出そうとした時点で、ランタイムエラーが発生します。このエラーは、次のようにメソッドを動的に追加することで解決できます。

class MyClass2
    def name
       "MyClass2: #{this}"
    end
end

 Javaのような強力な型チェックを持つ言語に慣れている開発者は、コンパイラやインタプリタがすべての型の使用を静的にチェックしない、このような「安全性に欠ける」柔軟性はプログラムの信頼性を低下させると思うようです。しかし、ランタイムの型チェックで発生するプログラムのバグは、テストですばやく検出できるので、ソフトウェアの信頼性は低下しません。それよりも、言語がより柔軟であるというメリットによって、プログラム自体の長さも開発時間も短くできます。

不明なメソッドの処理

 ダックタイピングなんて信頼できないとまだ思っているでしょうか? ではもう1つ、Rubyの裏技を紹介しましょう。Rubyクラスで不明メソッドを処理する方法です。以下は、2つのメソッド(定義済みのlengthと未定義のfoobar)を文字列オブジェクトに適用する簡単な例です。

markw$ irb
>> s = "this is a string"
=> "this is a string"
>> s.length
=> 16
>> s.foobar
NoMethodError: undefined method `foobar' for "this is a string"
:String from (irb):3

 未定義のメソッドの場合、エラーがスローされます。そこで、独自に作成したmethod_missingメソッドをStringクラスに「貼り付け」ます。

>> class String
>>   def method_missing(method_name, *arguments)
>>     puts "Missing #{method_name} (#{arguments.join(', ')})"
>>   end
>> end
=> nil
>> s.foobar
Missing foobar ()
=> nil
>> s.foobar(1, "cat")
Missing foobar (1, cat)
=> nil
>>

 Rubyのランタイムシステムは、オブジェクトのメソッドを検出できない場合、必ず初期設定で継承されているmethod_missingを呼び出し、単にNoMethodError例外を発生させます。この例では、この継承されているメソッドをエラーをスローしないメソッドでオーバーライドし、メソッド呼び出しの名前と引数を出力しています。次の例では、このメソッドをさらに再定義しました。今度は、メソッド名がfoobarであるかどうかを確認するためのチェックを定義しています(メソッド名は評価時にto_sを使って文字列に変換しています)。

>> class String
>>   def method_missing(method_name, *arguments)
>>     if method_name.to_s=='foobar'
>>       arguments.to_s.reverse  # return a value
>>     else
?>       raise NoMethodError, "You need to define #{method_name}"
>>     end
>>   end
>> end
=> nil
>> s.foobar(1, "cat")
=> "tac1"
>> s.foobar_it(1, "cat")
NoMethodError: You need to define foobar_it
        from (irb):38:in `method_missing'
        from (irb):43
        from :0
>>

 メソッド名がfoobarに等しい場合は戻り値が返され、等しくない場合はエラーがスローされます。

次のページ
Rubyのコードブロック

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

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

もっと読む

この記事の著者

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

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

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

Mark Watson(Mark Watson)

Javaコンサルタント。Java、人工知能、C++、知的エージェントに関する書籍を14冊執筆している。

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

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

この記事をシェア

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

おすすめ

アクセスランキング

アクセスランキング

イベント

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

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

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

メールバックナンバー

アクセスランキング

アクセスランキング