2010-12-02 1 views
0

私は約Object#tapを知っています。これは値をとり、その値を返します。しかし、ブロックを受け取り、ブロックによって評価される値を返すメソッドがありますか?ブロックの値を返すだけのRubyメソッドはありますか?

(以下スニペットよりも複雑である)this answerに私のコードを改善するために、私は何

def my_method(*args) 
    yield *args 
end 

deck = ['A', 'B', 'C'] 
my_method("A") {|value| deck.index(value).tap {|index| 
    STDERR.puts "Result of indexing for #{value.inspect} is #{index.inspect}" 
} } 
# Result of indexing for "A" is 0 
# => 0 

答えて

2

に、"A"を繰り返した

deck.index("A").tap {|index| 
    STDERR.puts "Result of indexing for #{"A".inspect} is #{index.inspect}" 
} 

を、変更したいです探しているのは本質的にLispやOCamlのletと同じです。新しい変数を大きなスコープに導入することなく一時的に値を識別子にバインドできるようにするものです。あなたがRubyでその構文でそのようなことをできるようにするものはありません。同等のルビーは次のようになります。私はあなたが繊維とそれを解決することができると思い

def let(*values) 
    yield *values 
end 
+0

スタート近いのではなく、終わり近く ' 'A''を入れて、それは可能ですか? –

0

:あなたは、もちろん同じようにメソッドを書くことができ

lambda {|value| deck.index(value).tap {|index| 
    STDERR.puts "Result of indexing for #{value.inspect} is #{index.inspect}" 
} }.call 'A' 

。ような何か:

def myfiber 
    block = lambda{nil} 
    loop{ block = Fiber.yield(block.call) } 
end 
f = Fiber.new {myfiber } 
f.resume 

puts "result: #{f.resume(lambda{1})}" 
puts "result: #{f.resume(lambda{5})}" 
puts "result: #{f.resume(lambda{2})}" 

はになります:

result: 1 
result: 5 
result: 2 
関連する問題