方法闭包在therubyracer中似乎不起作用

方法闭包在therubyracer中似乎不起作用,ruby,v8,therubyracer,Ruby,V8,Therubyracer,一旦我将一个方法存储在V8::Context中,该方法的所有后续实例以任何名称存储在任何上下文中,其行为与初始实例类似(即,就好像原始实例再次存储一样) 我试图通过以下方式隔离/证明问题: require 'V8' class TestClass def test_method self.inspect end end (1..2).each do |cxt_i| cxt = V8::Context.new [:test_method, :test_method2].

一旦我将一个方法存储在V8::Context中,该方法的所有后续实例以任何名称存储在任何上下文中,其行为与初始实例类似(即,就好像原始实例再次存储一样)

我试图通过以下方式隔离/证明问题:

require 'V8'

class TestClass
  def test_method
    self.inspect
  end
end

(1..2).each do |cxt_i|
  cxt = V8::Context.new
  [:test_method, :test_method2].each_with_index do |method_name, method_i|
    method = TestClass.new.method(:test_method)
    cxt[method_name.to_s] = method
    script = method_name.to_s+'()'
    puts "Context #{cxt_i}, method #{method_i+1} result is #{method.call}, V8 returns #{cxt.eval(script)}"
  end
end
将生成以下输出:

Context 1, method 1 result is #<TestClass:0x007fce2419cdb0>, V8 returns #<TestClass:0x007fce2419cdb0>
Context 1, method 2 result is #<TestClass:0x007fce2419b780>, V8 returns #<TestClass:0x007fce2419cdb0>
Context 2, method 1 result is #<TestClass:0x007fce2419abc8>, V8 returns #<TestClass:0x007fce2419cdb0>
Context 2, method 2 result is #<TestClass:0x007fce24199a98>, V8 returns #<TestClass:0x007fce2419cdb0>
Context 1,方法1的结果是#,V8返回#
上下文1,方法2的结果是#,V8返回#
上下文2,方法1的结果是#,V8返回#
上下文2,方法2的结果是#,V8返回#

这是一个弱参考问题。通过在内部循环中插入
GC.start
,我们强制对V8上下文中的弱引用进行垃圾收集。不过,它的速度大大减慢了

require 'v8'

class TestClass
  def test_method
    self.inspect
  end
end

(1..2).each do |cxt_i|
  cxt = V8::Context.new
  [:test_method, :test_method2].each_with_index do |method_name, method_i|
    method = TestClass.new.method(:test_method)
    cxt[method_name.to_s] = method
    script = method_name.to_s+'()'
    puts "Context #{cxt_i}, method #{method_i+1} result is #{method.call}, V8 returns #{cxt.eval(script)}"
    GC.start # <<<<=========
  end
end
需要“v8”
类TestClass
def测试方法
自检
结束
结束
(1..2).每个do|cxt|i|
cxt=V8::Context.new
[:test_method,:test_method2]。每个_都有_索引do |方法名称,方法i|
method=TestClass.new.method(:test\u方法)
cxt[方法名称到方法]=方法
script=method_name.to_s+'()'
放置“上下文{cxt_i},方法{method_i+1}结果为{method.call},V8返回{cxt.eval(脚本)}”

GC.start#我不明白,我的“V8返回”在上下文1和上下文2中是不同的(但在上下文中是相同的)。@mu太短了:我不理解你的评论。如果你的意思是你得到的结果和我的不同,你能分享你的代码和你的输出吗?和你的代码一样。我得到的V8返回值类似于
A
A
B
B
,其中您的值类似于
A
A
A
。仍然不是你期望的那样,但是更近了。@mu太短了:谢谢你的回复。介意分享你的版本信息吗?我的是:libv8(3.11.8.17 x86_64-darwin-12),ruby 1.9.3p194(2012-04-20修订版35410)[x86_64-darwin12.0.0](很抱歉,无法在此评论中使用缩进)。我刚刚用ruby 2.0.0和libv8-3.11.8.17再次尝试,得到了与您相同的结果。我做的第一个是1.9.2和libv8-3.3.10.4。啊,升级的乐趣。谢谢,马蒂。我不知道该怎么处理这些信息,但我很感激调查工作。我会给你赏金,因为我知道如果有更好的事情发生,我可以随时改变它。这是我的第一个赏金奖,我的理解是我“要么使用它,要么失去它”。-)刚刚和梅塔就赏金问题进行了长时间的交流。事实证明,一旦分配了赏金,我就不能移动,但在7天结束后有24小时的宽限期。有鉴于此,我将暂时不考虑悬赏,但我将确保在宽限期内处理悬赏,前提是在此之前悬赏还没有真正解决。如果有更好的答案/解决方法出现,我们都会受益。github(#260)上的这一问题与假设这确实是WeakRef问题的问题相同。建议升级到2.0oops,刚刚意识到你们在2.0上复制了它。在github上对此发表了评论。
Context 1, method 1 result is #<TestClass:0x007f8f13a26cd8>, V8 returns #<TestClass:0x007f8f13a26cd8>
Context 1, method 2 result is #<TestClass:0x007f8f135cca48>, V8 returns #<TestClass:0x007f8f135cca48>
Context 2, method 1 result is #<TestClass:0x007f8f135ceac8>, V8 returns #<TestClass:0x007f8f135ceac8>
Context 2, method 2 result is #<TestClass:0x007f8f135cdbf0>, V8 returns #<TestClass:0x007f8f135cdbf0>