Ruby:点击读写?

Ruby:点击读写?,ruby,Ruby,因此,如果我正确理解Object#tap使用yield生成一个临时对象,以便在流程或方法执行期间使用。从我对收益率的了解来看,它做了一些事情,比如,收益率取(物)和给(物)。dup到它所使用的方法所附加的块? 但当我这么做的时候: class Klass attr_accessor :hash def initialize @hash={'key' => 'value'} end end instance=Klass.new instance.instance_variab

因此,如果我正确理解Object#tap使用yield生成一个临时对象,以便在流程或方法执行期间使用。从我对收益率的了解来看,它做了一些事情,比如,收益率取(物)和给(物)。dup到它所使用的方法所附加的块? 但当我这么做的时候:

class Klass
attr_accessor :hash
  def initialize
   @hash={'key' => 'value'}
  end
end

instance=Klass.new
instance.instance_variable_get('@hash')[key] # => 'value', as it should

instance.instance_variable_get('@hash').tap {|pipe| pipe['key']=newvalue}

instance.instance_variable_get('@hash')[key] # => new value... wut?
我的印象是屈服->新的目标。我不知道这有多正确,我试着在ruby文档上查找它,但是Enumerator::yielder是空的,yield(proc)不在那里,光纤版本。。。我没有任何光纤,事实上,Ruby实际上不是明确要求包含“光纤”才能使用它们吗


因此,应该是实例变量的读取方法,而临时变量的写入方法是实例变量的读取/写入。。。这很酷,因为这正是我试图做的,并且在我查找将哈希作为实例变量处理的方法时意外发现的(对于一些大于我所习惯的用于命名变量数组的表),但现在我有点困惑,我找不到导致这种情况发生的机制的描述。

点击
不会复制接收器。块变量被分配给接收器本身。然后,
点击
返回接收器。因此,当您执行
点击{| pipe | pipe['key']=newvalue}
时,
点击
的接收器将被修改。据我所知

x.tap{|x| foo(x)}
相当于:

foo(x); x
y.bar; y

相当于:

foo(x); x
y.bar; y
对象#点击
再简单不过了:

VALUE
rb_obj_tap(VALUE obj)
{
    rb_yield(obj);
    return obj;
}
(摘自)。它只是让步,然后返回接收器。IRB中的快速检查显示,
yield
生成对象本身,而不是新对象

def foo
  x = {}
  yield x
  x
end

foo { |y| y['key'] = :new_value }
# => {"key" => :new_value }
因此,正如我们所希望的那样,
tap
的行为与
yield
是一致的