Webdialog - trouble passing array from JS to Ruby
-
@aerilius said:
If I am right the webdialog returns a string, for example
%(#000000)["[1,2,3]"]
...
Or youevalthe array ...Yup you are correct, and
eval()is the simplest way.. provided that on the Js side, you build the strings so Ruby'seval()can read them.@unknownuser said:
(https://developers.google.com/sketchup/docs/ourdoc/webdialog#add_action_callback)":1lvv2jxf]Your JavaScript in the webdialog will invoke the callback method with a string representing arguments to the callback method.
-
Make sure to read by Thomas Thomassen (ThomThom)
PDF download: WebDialogs - The Lost Manual β R1 09 November 2009
SCF Forum Post: WebDialogs - The Lost Manual β R1 09 November 2009
-
The webdialog returns a string, for example
%(#000000)["[1,2,3]"]. In Ruby, you always need to have a clear idea what type your value has. In JavaScript, you can mix incompatible types hoping that it will convert it and work as expected, but not in Ruby.
Don't miss to read the Ruby Newbies Getting Started GuideIf you apply an index to a string, you get the character code of the character at that index, example
"string"[0] = 115 # corresponds to 's'When you later added a string + the arraystring, you got the expected result because both were strings. You can't add an array to a string, because it would give:
Error: #<TypeError: (eval):151:in+': can't convert Array into String>The **+** method is not defined for different types. It exists separately for Numeric, for [Strings](http://www.ruby-doc.org/docs/ProgrammingRuby/html/ref_c_string.html#String._pl) and for [Arrays](http://www.ruby-doc.org/docs/ProgrammingRuby/html/ref_c_array.html#Array._pl), and if you have different types, you have to convert them into the same so that you can use one of the methods for it (either witharray.to_sorarray.inspect`).You could either parse the string into an array for example
@yv_width_array_rs = yv_width_rs[1..-2].split(",")which returns an array of strings.
If it should be floats (or integers) then you loop over the resulting array withcollectand convert each string of a float into a float with[to_f](http://www.ruby-doc.org/docs/ProgrammingRuby/html/ref_c_string.html#String.to_f):@yv_width_array_rs = yv_width_rs.scan(/\d+/).collect{|d| d.to_f} # or d.to_iOr you eval the array
begin @yv_width_array_rs = eval(yv_width_rs) rescue @yv_width_array_rs = [] endwhich you should absolutely avoid if there is an alternative way.
-
When you experience trouble with Ruby <-> JavaScript check the compiled string you send backwards and forwards. You will when quickly see syntax errors.
-
Thank you all!! Now I have something to try out.

-
@aerilius said:
Or you eval the array
begin > @yv_width_array_rs = eval(yv_width_rs) > rescue > @yv_width_array_rs = [] > endHere's a good place to show, how to use the
rescuekeyword, in modifier position (and save 4 lines of code.)@yv_width_array_rs = eval(yv_width_rs) rescue [] -
Aerilius, Im a little impressed.
When you quote my code, you use different variable-names than the ones from my example.
The funny thing is, the variable-names you use is the one I actually use on my own computer, before I started to look at arrays... Are you psychic or something??
-
I'm not psychic but rather impressed/surprised myself. That are the variable names that you posted
and after submitting my response, you had modified/improved the original question that I didn't recognize it anymore 
-
ah ok

Anyway, it finally works with this "simple" solution:
my_dialog.add_action_callback("get_array") do |web_dialog,yv_array| @YV_array = yv_array.scan(/\d+/).collect {|d| d.to_i} endI wonder why the eval-rescue solution has to be avoided? Is it slow?
Thanks to all of you. - Aerilius, Dan, Thomthom
Gratias Ad Omnes
-
@rvs1977 said:
I wonder why the eval-rescue solution has to be avoided? Is it slow?
ALL String operations in Ruby 1.8.x are slow.
eval()is the Ruby code parser.. so it is a very large method (actually a C-side function.)But I cannot see it being slower than the 2 iterator methods you are using, in addition to the type converter.
But it works... and you understand how it works. If speed is not an issue, then go with it ...

Also if you KNEW each numeric was separated by a "," then you also do:
@YV_array = yv_array.split(',').map{|i| i.to_i}
Advertisement