2009-07-14 9 views
1

RubyとDoブロックの学習。多くのC#から来て、私はDoのことを思い出させたことはあまり見えませんでしたが、VBはWithステートメントと私が望んでいたものが頭に浮かんでいました(おそらくそれは見たことがありますか? DoとWithという2つの文は似ています。DoブロックはWithステートメントと同じですか?

VBのWithステートメントはRubyのDoブロックと同じですか?

EDIT:

は、この例を見てみましょう、ActiveRecordのオブジェクトTheBookは、データベーステーブルにマップ:

TheBook.new do |book| 
book.title = "my book" 
book.writer = "some author" 
end 

私はそれを見てからちょうど取得するかを理解します。私は上記の情報で私のデータベースに新しいレコードを取得することを知っていますが、私は理由を知らない。なぜ書籍はTheBook.newになりましたか?それを右から左に読むのですか?

答えて

8

ルビーブロック(doendで区切るもの)は、基本的にはclosuresです。 VBのwithは、変数名を何度も繰り返し入力する必要がないようにする文法的な砂糖です。

3

これは同じではありません。 Rubyブロックは無名関数(技術的にはクロージャ)で、渡されるメソッドによって実行されます。例えば、スニペットは、100までの偶数番号を取得する:

(1..100).select do |num| 
    num % 2 == 0 
end 

select方法は、その数が選択基準と一致するかどうかを決定するために、引数としてシーケンス内の各番号のブロックを呼び出します。

(通常、これは(1..100).select {|num| num%2 == 0}のように書かれることになる - 。。それは違いはありませんdo構文は、中括弧とまったく同じです)

+0

私にはこれがスローされていると思います。同じ行にあります。私はもっ​​と感覚的なあなたのような人と、より意味のある人を見てきました。 – johnny

+3

それは議論です。 'def mymethod(arg)'を書くときに、メソッドの引数が同じ行にある方法と同じであると考えてください。 do-syntaxは通常複数行のブロック用であり、中括弧は通常このような単一行の場合に使用されます。 – Chuck

5

主に多くのルビーのないC#の開発者なので、自分自身を経験し、私はあなたの混乱を理解しています。

C#2.0のanonymous delegatesとC#3.0のlambda expressionsの概念に精通している場合は、これがより意味があります。

あなたのRubyのActiveRecordの例では、匿名デリゲートを使用してC#2.0で表現することができます

TheBook.New ((delegate TheBook book){ 
    book.title = "my book"; 
    book.author = "some author"; 
}); 

またはC#3.0で、次のようにラムダ式を使用して:

TheBook.New (book => {book.title = "my book"; book.author = "some author"}); 

基本的に "やる" ブロックが来ますあなたが引数として関数を期待するメソッドを持っている場合、またはC#のデリゲートを演奏してください。

1

実際には、ソースを見ることによってこの方法が何をしているのか少し知ることができます。 ActiveRecordの::ベースから:

def initialize(attributes = nil) 
    @attributes = attributes_from_column_definition 
    @attributes_cache = {} 
    @new_record = true 
    ensure_proper_type 
    self.attributes = attributes unless attributes.nil? 
    self.class.send(:scope, :create).each { |att,value| self.send("#{att}=", value) } if self.class.send(:scoped?, :create) 
    result = yield self if block_given? 
    callback(:after_initialize) if respond_to_without_attributes?(:after_initialize) 
    result 
end 

この質問に対する関心のラインがresult = yield self if block_given?です。ルビでは、yieldメソッドは、関数に渡されたブロック(与えられた例では、doendの間の部分)と、使用されるパラメータを呼び出します。この場合、ブロックに与えられるパラメータはselfです。この特定のブロックのインスタンスは、実際にはVisual Basicで言及したwithの機能を複製してしまいます。なぜなら、新しく作成されたActiveRecordオブジェクトをブロックに渡すためです。しかし、他の答えで説明したように、それ。

2

は、私はそれがこのようにそれを説明し、彼のチュートリアルでWhyPoignantだったと思う:パイプは ブロックに各反復の値を指示するよう

|varname|です。

letが、ファイルの各行を読みたいと言う:(ここでは単にputs line

file.each_line do |line| 
    puts line 
end 

file.each_lineはあなたにいくつかのデータを与え、そしてあなたがブロックにそのデータを指示する|line|を使用します。

Literraly:ファイルを読み込み、各行ごとに画面に表示します(正確には標準出力)

私はしばしばそのようなコードを書いています:elements.each do |element| ...

関連する問題