评论后编辑的第二次尝试
# This solution has a limit you have to return the `Proc` itself
with_proc = proc do |aproc, others|
aproc.instance_variable_set(:@a, aproc.instance_variable_get(:@a) || 0)
aproc.instance_variable_set(:@a, aproc.instance_variable_get(:@a) + 1)
p self: aproc, arg: others, '@a': aproc.instance_variable_get(:@a)
aproc
end
prc = with_proc.(with_proc, :foo)
# => {:self=>#<Proc:0x000055864be1a740@pro_self.rb:1>, :arg=>:foo, :@a=>1}
puts "prc: #{prc}"
puts "prc.equal?(with_proc): #{prc.equal?(with_proc)}"
# => prc: #<Proc:0x000055864be1a740@pro_self.rb:1>
# => prc.equal?(with_proc): true
prc.call(prc, :bar)
puts "prc @a: #{prc.instance_variable_get(:@a)}"
# => {:self=>#<Proc:0x000055864be1a740@pro_self.rb:1>, :arg=>:bar, :@a=>2}
# => prc @a: 2
other_prc = prc.call(prc.clone, :baz)
puts "other_prc: #{other_prc}"
# => {:self=>#<Proc:0x000055864be1a0b0@pro_self.rb:1>, :arg=>:baz, :@a=>3}
# => other_prc: #<Proc:0x000055864be1a0b0@pro_self.rb:1>
other_prc.call(other_prc, :qux)
#=> {:self=>#<Proc:0x000055864be1a0b0@pro_self.rb:1>, :arg=>:qux, :@a=>4}
prc.call(prc, :quux)
# => {:self=>#<Proc:0x000055864be1a740@pro_self.rb:1>, :arg=>:quux, :@a=>3}
使用此解决方案,您可以返回任何需要的东西
prc = proc do |ref_to_self, others|
self_reference = ref_to_self.instance_variable_get(:@ident)
self_reference.instance_variable_set(:@a, self_reference.instance_variable_get(:@a) || 0)
self_reference.instance_variable_set(:@a, self_reference.instance_variable_get(:@a) + 1)
p ({self: self_reference.instance_variable_get(:@ident),
arg: others,
'@a': self_reference.instance_variable_get(:@a)})
end
prc.instance_variable_set(:@ident, prc)
prc.call(prc, :foo)
puts "prc: #{prc}"
prc.call(prc, :bar)
puts "prc @a: #{prc.instance_variable_get(:@a)}"
other_prc = prc.clone
other_prc.instance_variable_set(:@ident, other_prc)
other_prc.call(other_prc, :baz)
puts "other_prc: #{other_prc}"
other_prc.call(other_prc, :qux)
prc.call(prc, :quux)
# {:self=>#<Proc:0x00005559f1f6d808@pro_self.rb:71>, :arg=>:foo, :@a=>1}
# prc: #<Proc:0x00005559f1f6d808@pro_self.rb:71>
# {:self=>#<Proc:0x00005559f1f6d808@pro_self.rb:71>, :arg=>:bar, :@a=>2}
# prc @a: 2
# {:self=>#<Proc:0x00005559f1f6d1f0@pro_self.rb:71>, :arg=>:baz, :@a=>3}
# other_prc: #<Proc:0x00005559f1f6d1f0@pro_self.rb:71>
# {:self=>#<Proc:0x00005559f1f6d1f0@pro_self.rb:71>, :arg=>:qux, :@a=>4}
# {:self=>#<Proc:0x00005559f1f6d808@pro_self.rb:71>, :arg=>:quux, :@a=>3}
第一次尝试
评论后编辑。我知道没有直接的方法来引用您传递给new 的块内的Proc 对象我试图使用tap 更接近您的代码。
我希望这可以帮助
def proc_reference_to_self(a_proc)
first = Proc.new do
puts "Hello"
end.tap(&a_proc)
end
second_prc = Proc.new do |first|
p first
first.call
puts "second_prc"
p second_prc
end
# This execute second_prc as a block
proc_reference_to_self(second_prc)
# first and second are different objects but you can still reference first
# inside second_proc
# <Proc:0x000055603a8c72e8@ruby_array_of_paths.rb:75>
# Hello
# second_prc
# <Proc:0x000055603a8c7338@ruby_array_of_paths.rb:81>