Appcelerator Titanum Desktop の Javascript→Rubyでの不具合
Javascriptから数値要素の配列をRubyのメソッドに渡したときに、そのままではメソッド内でinjectが使えないです。
対処法としては、今時点ではeachを使うか、Rubyのメソッド内で明示的に数値要素の配列に変更すればinjectをつかえるようになります。
以下試してみたコード
<html> <head> <meta http-equiv="content-type" content="text/html;charset=UTF-8" /> </head> <body> <div> <button onclick="array_test()">array_test</button> <script type="text/ruby"> def rb_array_test(arr) alert(arr.class) # undefined alert(arr.to_s) # #<RubyKList:0xxxxxxxxx> alert(arr.inspect) # #<RubyKList:0xxxxxxxxx> alert(arr.respond_to? :each) #false alert(arr.instance_of?(Array)) #false alert(arr.respond_to?:inject) #false n=0 arr.each {|i| n+=i} # success. display 10 alert(n) # alert(arr.inject {|r,i| r + i }) #failure arr_i =arr.map {|n| n.to_i } alert(arr_i.class) # undefined alert(arr_i.to_s) # 1234 alert(arr_i.inspect) # [1,2,3,4] alert(arr_i.respond_to? :each) # true alert(arr_i.instance_of?(Array)) # true alert(arr_i.respond_to? :inject) #true alert( arr_i.inject {|r,x| r+x } ) # 10 arr_s =arr.map {|n| n.to_s } alert(arr_s.class) # undefined alert(arr_s.to_s) # 1.02.03.04.0 alert(arr_s.inspect) # ["1.0","2.0","3.0","4.0"] alert(arr_s.respond_to? :each) # true alert(arr_s.instance_of?(Array)) # true alert(arr_s.respond_to? :inject) # true alert( arr_s.inject {|r,x| r+x } ) # 1.02.03.04.0 end </script> <script> function array_test(){ rb_array_test([1,2,3,4]); } </script> </body> </html>
渡ってきた段階では、RubyKListというkroll上のオブジェクト(?)になっていて、RubyのArrayになっておらずeachを持ってるかチェックしてもfalseが返ってくるが、eachは呼び出すと呼び出せる。
明示的に数値要素の配列にしてから処理すると期待通りの動作。
あとおまけで文字列要素の配列に変更もやってみました。
ざざっとgrepかけてみて、該当しそうなコードを眺めてみただけで、krollが行っている処理をまだ追い切れてません。
変換時に文字列、数値の判定かなにかでしくじってる感じでしょうか?
なお、WinでもOS Xでも確認済みです。
とりあえず公式の掲示板に報告しつつ、調査する予定です。
あと、kroll自体の詳細な仕掛けも一回きっちり調べた方がよさそう。