我知道Object#tap
,它接受一个值并返回该值。但是有一个方法需要一个块并返回块所评估的值吗?
要改进this answer中的代码(这比下面的代码段更复杂),我想改变
deck.index("A").tap {|index|
STDERR.puts "Result of indexing for #{"A".inspect} is #{index.inspect}"
}
,重复"A"
,进入
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
答案 0 :(得分:2)
您正在寻找的内容基本上等同于Lisp或OCaml中的let
- 允许您临时将值绑定到标识符而不将新变量引入更大范围的内容。没有任何东西可以让你在Ruby中用这种语法做这样的事情。等价的Ruby将是:
lambda {|value| deck.index(value).tap {|index|
STDERR.puts "Result of indexing for #{value.inspect} is #{index.inspect}"
} }.call 'A'
你当然可以写一个像:
这样的方法def let(*values)
yield *values
end
答案 1 :(得分:0)
我认为你可以用纤维解决它。类似的东西:
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