私は Java が最初に登場したときからずっと使っていますが、過去 5 年間で、最も単純なことを実行するのがいかに複雑になったかで燃え尽きてしまいました。私は精神科医の勧めで Ruby を学び始めています。つまり、私の同僚 (若くてクールな同僚 - 彼らは Mac を使用しています!) です。とにかく、彼らが繰り返し繰り返していることの 1 つは、Ruby は Java のような古くてボロボロの言語に比べて「柔軟な」言語であるということですが、それが何を意味するのか、私にはまったくわかりません。ある言語が別の言語よりも「柔軟」である理由を誰か説明できますか? お願いします。動的型付けの要点はある程度理解でき、それが簡潔性にどのように役立つかがわかります。そして、Ruby の構文は、まあ、美しいです。ほかに何か?動的型付けが主な理由ですか?
7 に答える
また、(Java の意味では) クラスレスですが、完全にオブジェクト指向 (プロパティ パターン) であるため、定義されていなくても任意のメソッドを呼び出すことができ、メソッドの作成など、呼び出しに動的に応答する最後のチャンスが得られます。その場で必要に応じて。また、Ruby はコンパイルを必要としないため、必要に応じて実行中のアプリケーションを簡単に更新できます。また、オブジェクトは、ミックスインを介して、存続期間中にいつでも別のクラス/オブジェクトから突然継承できるため、柔軟性のもう 1 つのポイントです。とにかく、Ruby と呼ばれるこの言語は実際には Java と同じくらい長く存在しており、非常に柔軟で多くの点で優れているという子供たちに同意しますが、それが美しい (構文に関して) とはまだ同意できません。C はより美しい私見(私はブラケットの吸盤です)が、美しさは主観的です。
動的型付けはそれをカバーするにはほど遠いです。大きな例として、Ruby は多くのケースでメタプログラミングを容易にします。Java では、メタプログラミングは困難であるか不可能です。
たとえば、プロパティを宣言する Ruby の通常の方法を取り上げます。
class SoftDrink
attr_accessor :name, :sugar_content
end
# Now we can do...
can = SoftDrink.new
can.name = 'Coke' # Not a direct ivar access — calls can.name=('Coke')
can.sugar_content = 9001 # Ditto
これは特別な言語構文ではなく、Module クラスのメソッドであり、簡単に実装できます。のサンプル実装は次のattr_accessor
とおりです。
class Module
def attr_accessor(*symbols)
symbols.each do |symbol|
define_method(symbol) {instance_variable_get "@#{symbol}"}
define_method("#{symbol}=") {|val| instance_varible_set("@#{symbol}", val)}
end
end
end
この種の機能により、プログラムの表現方法にかなりの柔軟性が得られます。
言語機能のように見えるものの多く (そして、ほとんどの言語で言語機能となるもの) は、Ruby の通常のメソッドにすぎません。別の例として、配列に格納されている名前の依存関係を動的に読み込みます。
dependencies = %w(yaml haml hpricot sinatra couchfoo)
block_list %w(couchfoo) # Wait, we don't really want CouchDB!
dependencies.each {|mod| require mod unless block_list.include? mod}
ブロック、閉鎖、多くのもの。午前中にもっと良い回答が得られると確信していますが、一例として、10 分前に書いたコードを次に示します。保留中のものだけの配列を返したい。同等のJavaが何であるかはわかりませんが、この1行のメソッドではないと思います:
def get_all_pending
scheduled_collections.select{ |sc| sc.is_pending? }
end
同じことのより簡単な例は次のとおりです。
[0,1,2,3].select{|x| x > 1}
[2,3]を生成するもの
好きなもの
- あなたの主張を理解するためのより少ないコード
- コード ブロック (Proc、ラムダ) を渡すのは楽しく、より小さなコードになる可能性があります。例えば
[1, 2, 3].each{|x| puts "Next element #{x}"}
- PERLのスクリプトのルーツを持っています..正規表現を使用したファイルの解析などのルーチンをスライスするのに非常に便利です. 全て
- Hash や Array などのコア データ構造クラス API はうまくできています。
- メタプログラミング (動的な性質のため) - カスタム DSL を作成する機能 (たとえば、Rails は Ruby で記述された WebApps の DSL と呼ぶことができます)
- ほぼすべての宝石を生み出しているコミュニティです。
ミックスイン。新しい機能を追加するために Ruby クラスを変更するのは簡単です。
ダックタイピングとは、宣言された型に基づくのではなく、型が実装するメソッドによって型が同等であると見なされるという事実を指します。具体的な例を挙げると、Ruby の多くのメソッドは、IO のようなオブジェクトを使用してストリームを操作します。これは、オブジェクトが IO タイプのオブジェクトとして渡すことができる十分な関数を実装する必要があることを意味します (それは十分にアヒルのように聞こえなければなりません)。
つまり、Java よりも少ないコードで同じことを行うことができます。ただし、動的言語については、すべてが優れているわけではありません。Java (およびその他の厳密に/静的に型付けされた言語) が提供するコンパイル時の型チェックのすべてを多かれ少なかれ放棄します。Ruby は、間違ったオブジェクトをメソッドに渡そうとしているかどうかを単純に認識できません。実行時エラーが発生します。また、コードが実際に呼び出されるまで実行時エラーは発生しません。
笑いのために、言語の柔軟性のかなり厄介な例:
class Fixnum
def +(other)
self - other
end
end
puts 5 + 3
# => 2