This morning I had an interesting thought about how we could possible have C macro like functionality in RubyMotion, and I believe I've come up with a somewhat suitable solution, though it could definitely still use some work.
The basic idea is the anything between the comments
#MEND will be executed before compilation is done. If a file that is in
app.files contains these comments, then the file in
app.files is replaced with a preprocessed version in the
Lets look at an example to explain.
Setting up the preprocessor
To actually use the preprocessor, you need to do a few things.
First, copy and paste
lib/preprocessor.rb in your project from this gist: https://gist.github.com/FluffyJack/9678692
Then require the preprocessor in your Rakefile and call it in your setup block.
# -*- coding: utf-8 -*- $:.unshift("/Library/RubyMotion/lib") require 'motion/project/template/ios' require './lib/preprocessor' begin require 'bundler' Bundler.require rescue LoadError end Motion::Project::App.setup do |app| # Use `rake config' to see complete project settings. app.name = 'Macros' Preprocessor.process(app) end
Using the preprocessor
Lastly, start using the syntax! Here is an example where we're adding a
test method to our
AppDelegate and calling it in the did finish launching method, but only if we do
class AppDelegate def application(application, didFinishLaunchingWithOptions:launchOptions) #MBEGIN #if ENV['test'] # @contents << "self.test" #end #MEND true end #MBEGIN #if ENV['test'] #@contents << "def test" #@contents << " puts 'test'" #@contents << "end" #end #MEND end
The code in the macro blocks is executed in the context of the processor, and so to add lines of code to the file, we just append it to the
@contents instance variable of the
ProcessedFile. It also means we have access to the
I thought this was pretty awesome because it means we can run ruby code to preprocess our files. This could come in handy for debugging code, or platform specific code, because the result will never end up in the compiled files unless we tell it to.
If you run just
rake, the preprocessed file that gets created will simply look like this.
class AppDelegate def application(application, didFinishLaunchingWithOptions:launchOptions) true end end
But if you run
test=true rake then the extra code will be added.
class AppDelegate def application(application, didFinishLaunchingWithOptions:launchOptions) self.test true end def test puts 'test' end end
It's actually horribly formatted, but I've cleaned it up here. Seeming it's just a temp file though, we'll never be working with these preprocessed files.
Would you use this?
Tell me on twitter if you would use this in your project, if enough people are interested I'll create a gem. https://twitter.com/RubyMotionTV