What have you found for these years?

2012-06-16

A Taste of RubyMotion

edited 2012-06-16 21:58
* I forgot to mention that, a 8,000 lines of Ruby file needs 1 minute
to be compiled on my MacBook Pro i5.

* Compiled binary is about 1M to 2M for a hello world program.



Yesterday I got a chance to try RubyMotion, and here's some
of the first impression:

* It would install files under /Library/RubyMotion, and create a symlink
from /Library/RubyMotion/bin/motion to /usr/bin/motion

* The toolchain is quite convenient, comparing to Xcode, and I think
it's implemented in Ruby, so that we would use `rake` to accomplish
tasks. Note that this `rake` is not run by RubyMotion (MacRuby),
so that we can write "normal" Ruby code for tasks.

* By "normal" Ruby code, I mean in RubyMotion, we're not really
writing Ruby codes. There's a syntax change, and this one is not Ruby:
def application(application, didFinishLaunchingWithOptions:launchOptions)
end
* You can't use `require`, it would cause a RuntimeError.
* You can't use `define_method`, it would cause a RuntimeError.
* You can't use `module_eval`, it would cause a RuntimeError.
* You can't undefine `hash` method, it would cause a RuntimeError.
* You can't use ..., it would cause a RuntimeError.
* I didn't test it intensively, the above are found by trying to use
rest-client and failed, and I stopped trying to patch it to make it work.

* So basically not much existing Ruby code you can use in RubyMotion.
I wrote a simple script which would try to bundle all necessary files into
a huge Ruby file by remove `require` and append the contents into the
output file, and see if that would work!

Unfortunately, too many failures and yes, I can patch them very easily,
but no, I can't make this process automatically, unless I write a real
compiler or preprocessor which would compile `module_eval` statically.
Hey, many people actually do meta-programming in "compile time", it's
not necessary to make it work in runtime. `require` could be ignored, too.

I mean, I feel RubyMotion is not very friendly to existing Ruby codes.
There's much can be done here, instead of raising RuntimeError.
A preprocessor would be much appreciated.

If you're interested in how I did it, here's the code: bunmo.rb
require 'rubygems/specification'
require 'rubygems/dependency'
require 'net/http'
require 'openssl'
require 'zlib'

$bunmo_output = File.open("#{ARGV.first}.rb", 'a')
$bunmo_loaded = {}

class Object
  alias_method :require_ruby, :require
end

def require name
  return if $bunmo_loaded[name]
  path = Gem.find_files("#{name}.rb").first
  return warn("#{name} not found: #{caller[-3]}") unless path
  $bunmo_loaded = path
  require_ruby name
  $bunmo_output.puts(File.read(path).
    gsub(/require(\(| ).+$/, ''))
end

require ARGV.first
* It's very weird that `initialize` might not be called by `new`,
and it's not callable during runtime?? That's why I name it
`construct` instead of `initialize` in app_delegate.rb :(

* A typo would cause a RuntimeError instead of a compile time error.
This is needed for Ruby, but not really for RubyMotion, given that
you cannot do `define_method` nor `module_eval`, etc, so the names
should be static, thus typo should be captured in compile time.

* Aside from those Ruby issues, calling iOS (Cocoa?)'s API with
Ruby's syntax is quite delightful, comparing to use Objective-C.

* But it's still the flavour of Objective-C, instead of Ruby.
This is stupid for me:
r, g, b, a = rainbows
UIColor.colorWithRed(r, green:g, blue:b, alpha:a).set
I would prefer this instead:
UIColor.colorWith(*rainbows).set
* During the exploration building a simple hello world rainbows program,
I reminded my old days with GUI. Glad that I haven't forgot them,
it's quite helpful when I saw some context error while I tried to render
or update the screen in the wrong method.

* So GUI experience, Objective-C experience, iOS experience,
all of them are quite helpful, but I do only have C/C++ GUI experience.
There's some Objective-C related compiling problems I cannot really
fix, such as what is a framework? How do I link against them?

Overall, I think it's a good product which would definitely help me
catch up iOS development, but I guess I still need to fight with
Objective-C concepts and iOS development, and stop thinking to
port existing Ruby codes to RubyMotion, since it would need a lot of
effort I guess. Well, only if I decided to put my direction onto
RubyMotion, won't I really try to build one. It should have much
potential though.

We'll see.

All codes in this gist.

0 retries:

Post a Comment

All texts are licensed under CC Attribution 3.0