题
我知道 Object#tap
, ,它具有值并返回该值。但是,是否有一种方法可以采用块并返回块评估的值?
改善我的代码 这个答案 (比下面的摘要更为复杂),我想更改
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
解决方案
您要寻找的本质上是 let
在LISP或OCAML中 - 使您可以在不将新变量引入较大范围的情况下临时将值绑定到标识符。没有什么可以让您在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
其他提示
我认为您可以用纤维解决。就像是:
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
不隶属于 StackOverflow