Load Order with RubyMotion May 6 2012


Because of the way RubyMotion compiles your application, you may run into dependency issues between your ruby files. By default, RubyMotion uses a simple Dir.glob command to load your files:

1
Dir.glob(File.join(app.project_dir, 'app/**/*.rb'))

Suppose you create a custom module under app/lib/foo.rb with some convenience methods:

1
2
3
4
5
module Foo def self.bar "bar" end end

And then you include it in your AppDelegate class:

1
2
3
4
5
6
7
8
class AppDelegate include Foo def application(application, didFinishLaunchingWithOptions:launchOptions) @bar = self.bar true end end

When you run rake, you may run into this:

1
2
3
4
5
(main)>> 2012-05-06 16:58:49.270 app[88253:f803] *** Terminating app due to uncaught exception 'NameError', reason: 'uninitialized constant AppDelegate::Foo (NameError) ' *** First throw call stack: (0x156a022 0x1b0cd6 0xd1c34 0x2377 0x2225) terminate called throwing an exception

The basic solution, which RubyMotion's documentation suggests, is to use the app.files_dependencies option in your Rakefile:

1
2
3
4
5
Motion::Project::App.setup do |app| # Use `rake config' to see complete project settings. app.name = 'app' app.files_dependencies 'app/app_delegate.rb' => 'app/lib/foo.rb' end

However, if you are building a large app, and want Foo to be available to all your classes, you probably don't want to have dozens of 'app/baz.rb' => 'app/lib/foo.rb' entries. In my project, I'm just altering the array of files from Dir.glob instead, ensuring my modules get loaded first:

1
2
app.files = Dir.glob(File.join(app.project_dir, 'app/lib/**/*.rb')) | Dir.glob(File.join(app.project_dir, 'app/**/*.rb'))

comments powered by Disqus