2012-02-12 8 views
1

Rubyブロックに関する質問があります。 は、例えば、私はRubyのクラスがあります。ブロックハック、ブロックを簡略化する方法

class NewClass 
    def initialize 
    @a = 1 
    end 

    def some_method 
    puts @a 
    end 
end 

私はそのような何かを行うと:

NewClass.new do |c| 
    c.some_method 
end 

すべてが良いですが、何とか好きなことを行うための任意の可能性があります:

NewClass.new do 
    some_method 
end 

アイデア

+3

関連質問:http://stackoverflow.com/questions/9225946/dsl-block-without-argument-in-ruby –

答えて

1

yieldがないので、現在のコードではブロックを無視します。最初の例で何をしようとしているのかは、yield selfイディオムがinitializeにある必要があります。

最初にブロック変数が必要な理由は、some_methodの受信者が2番目の例になることを考えてください。明示的な受信者がなければ、それは最上位レベルmainです(このコードはもちろん、他のクラスの一部である場合を除き、囲むクラスはselfとなります)。そのトピックの詳細については、Dave Thomasのブログ投稿Changing self in Ruby(またはNiklas B.がコメントで指摘したYehuda Katz' post)を参照してください(このコメントは「proc呼び出し」の部分をクリアしています)。

編集:これは、ことができます

class NewClass 
    def initialize 
    @a = 1 
    end 

    def some_method 
    puts "Hello: #@a" 
    end 

    def self.build(&block) 
    x = self.new 
    x.instance_eval(&block) 
    x 
    end 
end 

NewClass.build do 
    some_method 
end 

あなたがブロック変数せずにブロックを実行するための新しいインスタンスを返します。これが動作しているようですが、私はyield selfバージョンおよび例1を好む、と述べているすべての変数に代入するクラスなど

+1

+1、これはIMO、唯一の良い答えです。しかし、私はあなたに[メタプログラミングで '自己 'の役割についてのYehuda Katzのブログ記事]にリンクすることをお勧めします(http://yehudakatz.com/2009/11/15/metaprogramming-in-ruby-its-all-about- the-self /)の代わりにデーヴ・トーマス氏の記事: –

+0

が更新されました。ありがとうございました。 –

0

instance_evalを使用すると、その作業を行う必要があります。しかし、あなたが何をしているのか分からない限り(それはただの怠惰からではありません)私はそれに対してアドバイスをし、あなたの元のアプローチに従います。

def initialize(&block) 
    @a = 1 
    self.instance_eval(&block) if block_given? 
end 
+0

元のアプローチは機能しません。 –

2
class NewClass 
    def initialize(&block) 
    @a = 1 
    instance_eval(&block) 
    end 

    def some_method 
    puts @a 
    end 
end 



NewClass.new do 
    some_method 
end 
+2

ブロックされていないと失敗します。 –

関連する問題