我曾经写过类似let的表达式 - 带有词法范围。
所以我自己编写(很遗憾,但多线程会失败):
# Useful thing for replacing a value of
# variable only for one block of code.
# Maybe such thing already exist, I just not found it.
def with(dict, &block)
old_values = {}
# replace by new
dict.each_pair do |key, value|
key = "@#{key}"
old_values[key] = instance_variable_get key
instance_variable_set key, value
end
block.call
# replace by old
old_values.each_pair do |key, value|
instance_variable_set key, value
end
end
我在google中搜索ruby的这种构造(可能是其他块定义),但是找不到它。也许我松了一些东西?红宝石人在这种情况下使用了什么?
PS:对不起我的英语不好,你知道。
UPD:我很想提供一些使用示例:
@inst_var = 1
with :inst_var => 2 do
puts @inst_var
end
puts @inst_var
输出:
2
1
答案 0 :(得分:4)
一个想法:
class Object
def let(namespace, &block)
namespace_struct = Struct.new(*namespace.keys).new(*namespace.values)
namespace_struct.instance_eval(&block)
end
end
message = let(language: "Lisp", year: "1958", creator: "John McCarthy") do
"#{language} was created by #{creator} in #{year}"
end
单值scopping更明确,因为您在块参数中命名变量。这个抽象被称为as
,pipe
,into
,scope
,let
,peg
,...,你的名字,它是都一样:
class Object
def as
yield self
end
end
sum = ["1", "2"].map(&:to_i).as { |x, y| x + y } #=> 3
答案 1 :(得分:2)
您不能指定要初始化的值,但可以将变量声明为该块的显式本地:
x = 'external value'
puts x
[1,2,3].each do |i; x|
x = i
puts x
end
puts x
这将导致:
external value
1
2
3
external value