2013-05-30 3 views
2

Как только я храню метод в контексте V8 ::, все последующие экземпляры этого метода, хранящиеся в любом контексте под любым именем, ведут себя как исходный (то есть, как если бы исходный экземпляр был снова хранится).Закрытие метода не работает в therubyracer

Я пытался изолировать/продемонстрировать проблемы со следующим:

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> 
+0

Я не получаю, что мой "V8 возвращает" различны в течение контексты 1 и 2 (но то же самое в контексте). –

+0

@mu слишком коротко: я не понимаю ваш комментарий. Если вы имеете в виду, что у вас разные результаты, чем я, можете ли вы поделиться своим кодом и результатами? –

+0

Тот же код, что и у вас. Я получаю значения V8, такие как 'A',' A', 'B',' B', где ваши - 'A',' A', 'A',' A'. Все еще не совсем то, чего вы ожидаете, но ближе. –

ответ

1

Это слабая ссылка вопрос. Вставив 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 

Выход:

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> 

рубин -v является ruby 2.0.0p195 (2013-05-14 revision 40734) [x86_64-linux], libv8 является 3.11.8.17 x86_64-linux

+0

Спасибо, Мэтти. Не уверен, что делать с этой информацией, но я ценю следственную работу. Я собираюсь наградить вас щедростью с пониманием того, что я всегда могу сдвинуть ее, если произойдет что-то лучшее. Это моя первая награда за награду, и я понимаю, что я «использую ее или теряю». ;-) –

+0

Просто был длинный обмен на мета о награждении за грант. Оказывается, я не могу переместить щедрость после назначения, но есть 24-часовой льготный период после окончания 7 дней. В свете этого, я собираюсь оставить щедрость не зная на данный момент, но буду следить за тем, чтобы я справлялся с ним в течение льготного периода, предполагая, что до этого он не был разрешен. –

+0

Если лучший ответ/обходное решение придет, мы все выиграем. –

 Смежные вопросы

  • Нет связанных вопросов^_^