- Only pass strings between JavaScript and Ruby, encoding in JSON strings if necessary.
  - In JavaScript, call Ruby methods with String arguments. JavaScript ints become Ruby Floats, so just use Strings to avoid potential confusion; JSON arguments will probably work and become hashes, but then you'll have to beware of the types of all the nested objects... if I need multiple values then I either supply them as more arguments or I call the Ruby method multiple times.
- In Ruby, check arguments for RubyKObject type. Sometimes arguments don't have the expected String type, so you'll want to convert them:
 
 if (term.class.name == "RubyKObject")
 term = term.toString()
 end
 - In Ruby, return String objects; if necessary, encode in JSON. Here's a simplistic method that works for me:
 
 # takes an argument which is any nesting of String, Array, Hash (and nil)
 # return a String holding JSON representation of the argument
 def self.strings_arrays_hashes_json(arg)
 if (arg == nil)
 "null"
 elsif (arg.class.name == "String")
 result = arg
 result = result.gsub("\"","\\\"")
 result = result.gsub("\\","\\\\")
 result = result.gsub("\/","\\/")
 result = result.gsub("\b","\\b")
 result = result.gsub("\f","\\f")
 result = result.gsub("\n","\\n")
 result = result.gsub("\r","\\r")
 result = result.gsub("\t","\\t")
 "\"" + result + "\""
 elsif (arg.class.name == "Array")
 recurse = arg.map { |elem| strings_arrays_hashes_json elem }
 "[" + recurse.join(", ") + "]"
 elsif (arg.class.name == "Hash")
 hashes = arg.to_a.map { |key, val|
 "\"#{key}\":#{strings_arrays_hashes_json(val)}" }
 "{" + hashes.join(", ") + "}"
 else
 "#{arg}"
 end
 end
 
 - In JavaScript, cast the results to a string (ie. toString()) and parse out the JSON if necessary (ie. JSON-js). It's crazy, but even an unused toString call can make a difference.
- Thankfully, you can trust nulls and nils; they convert to one another well.
 
- In JavaScript, call any Ruby methods before playing with the DOM. I've found that, if I have a lot of DOM manipulation, Ruby calls will work up to some point and then WHAM! after that point you get errors or crashes.
BTW, the direct-to-console debugging is your friend; the Ruby puts calls may not get flushed immediately, but this will:
Titanium.API.print("stuff\n"); 
When you start working this way, you'll notice that you're really pushed into a paradigm where you do simple visual manipulations in the browser as much as possible, but for any substantive changes to data you do a page-submit to pass the values to the same page, then you run your logic during the page initialization and then you rerender the whole page. It's unfortunate, but now I never have troubles. (... at least very few! Just kidding. I haven't had any mysterious Ruby errors or app crashes wherever I take these approaches.)
BTW, every time I hit a glitch, I look more closely at other approaches... but since I figure every tool will have its issues, I'm still sticking with the devil I know. Feel free to ask me later if I'm still sticking to it.
 
 Posts
Posts
 
 
 
 
No comments:
Post a Comment