经过一周的网络搜索,我什么也没找到,我想“如果我们太天真了,把一件东西
method_missing
定义?”
30分钟后,我可以从javascript调用ruby。
class MyFunc
# Called when no arguments are passed to JavaScript function
def call
#Execute any ruby code here!!
#You can also return values back to JavaScript!!
return 1
end
# Called when arguments are passed to JavaScript function
def value(*args)
if args.length == 0
# This will be called if the function is called without parenthesis in JS
# e.g. console.log(document.someFunc)
return nil
else
#This is called with the parsed arguments. Note: Functions passed in from JS are of type WIN32OLE. Theoretically this should be callable, but better would be to make a JS function which can call other JS functions
#Execute any ruby code here!!
puts "#{args.inspect}"
#Can also return values here as well
return 1
end
end
end
ie.document.setVar("myFunc",MyFunc.new})
您还可以初始化和访问实例变量:
class MyClass
def initialize
@hello = "world"
end
end
ie.document.setVar("myClass",MyClass.new})
#IN IE: document.myClass["hello"] //=> "world"
注:
有些事情可能会大错特错,甚至会导致红宝石崩溃。一些不起作用的例子:
-
直接评估对象:
document.myObj
. javascript将把函数解释为一个对象,也许正如人们所期望的那样。
-
获取不存在的价值并没有任何作用:
document.myObj["hello"]
.
-
设置不存在的值会导致Ruby崩溃:
document.myObj["hello"]=1
.
有些事情也毫无意义,例如我做了以下循环:
给定一个类:
class MyClass
def call
puts "Call"
end
def method_missing(m,*args,&block)
puts "#{m}(#{args.inspect})"
end
end
ie.document.setVar("obj",MyClass.new)
和javascript:
for(var i=0;i<24;i++){
document.obj[chars[i]]()
}
这将执行以字母字符命名的obj的每个函数。事实上,它在大多数情况下都是这样做的,然而有时它并不这样做。有时它会主叫
call
方法,如果是
document.obj.j()
它什么也做不了…
完整日志:
a([])
b([])
c([])
d([])
e([])
f([])
Hello world
h([])
i([])
k([])
Hello world
m([])
n([])
o([])
q([])
s([])
t([])
Hello world
v([])
w([])
x([])
y([])
Hello world
编辑
I've written a GIST
这使得这更容易实现。例如,通过
File
反对IE,您可以执行以下操作:
ie.document.setVar("RubyFile",WIN32OLE::getDispatch(File))