Why I'm Not Using RubyMotion in Production
joshsymonds.com
joshsymonds.com
But if you're going to stay closed source, you're asking me to just trust you that important (to me) bugs are going to get fixed fast enough. That is very hard to do.
That is the real value of open source. It's not about the money -- an extra $200 is nothing in a development budget. It's about being able to fix the bugs myself when they matter enough.
I wonder if there are any closed-source software shops that have a "pays us a premium to fix bug X first" option. Doesn't seem like it would work too well.
At a high price, you can get strong service guarantees.
At a zero price, you can use open source and manage the critical service yourself.
At a low but nonzero price, you get neither.
By that I mean, clients with budgets will opt for enterprise services. That's not necessarily fair, but humans like expensive stuff, especially when it's not their money.
The thing is, engineers who move into SaaS and try to tackle that middle ground tend to be shafted. This is why people like 'patio11 so often recommend aiming for the enterprisey folks - that's where you make a living.
Can you point to the company name? I am checking what is out there (EMRS).
RubyMotion would have been awesome a few years ago, but now that Obj-C has ARC, literals for dictionaries and arrays, and blocks (yes!), I can't help but think that RubyMotion has missed the boat. Learn Obj-C. Go to iTunes U, get Stanford CS193P, and have a bunch of fun.
- you can use the editor of your choice and the terminal instead of Xcode
- you can use the interactive console to debug your app or to live test new code
- you get all the great wrapper gems like BubbleWrap which are heavily influenced by the "rails way" of doing things
Because:
> you can use the editor of your choice and the terminal instead of Xcode.
This is possible with Obj-C, but using Xcode is a far superior experience to RubyMotion and any editor.
> you can use the interactive console to debug your app or to live test new code
Ditto for lldb in Xcode
> you get all the great wrapper gems like BubbleWrap which are heavily influenced by the "rails way" of doing things
There are plenty of powerful 3rd party Obj-C abstractions too.
XCode is not ideal for people accustomed to, say, vim. I love the static code analysis and the autocomplete and storyboards are pretty cool too. But having to edit text like a normal human instead of using vim sucks and the split pane handling is garbage. I would rather do all my dev in vim.
> using Xcode is a far superior experience to RubyMotion and any editor
Yesterday I had to convert a list of constants into mathematical operations. Took ten seconds to make the macro in vim, and then I ran it twenty times in a second. Compare with the five to ten minutes it would have taken doing option+arrow around the numbers to add characters before and after.
I've turned off all of Xcode's text editing functionality (except for esc to code complete) because it was interfering with typing instead of helping. I've tried to turn off all the "jump to error" stuff in the settings, but it still insists on jumping to the disassembly for main() when it hits an error.
I'd add that one not be fooled by the apparent verbosity of the "selectors", which is the ObjC equivalent of lisp parens that hits folks new to the language. Their cognitive overhead (for me) is rather low, and they make the code readable without profuse commenting. XCode has been a pleasure as well (despite the occasional crashes), due to the live code correctness feedback (thanks to llvm/clang), auto-complete and auto-correct.
Overall, practically everything's been improving in iOS land as far as I can tell.
Really appreciate the article and I am interested to see where this leads for RubyMotion.
They used a bug tracker that wasn't publicly viewable until they migrated everything to YouTrack earlier this year (I reported it last August).
I really hope that they get around to fixing this problem, it does make me a bit concerned that they are pushing big new features while such a serious issue seems to exists.
Now it's like, well, why not just use Objective-C? I sort of just wish I had my $200 back.
$200 is small potatoes.
Not only does the author have the courage to admit there are problems with RubyMotion that make it unfit for production use--and seriously, noticeable unexpected and difficult-to-reproduce-and-fix memory errors make any language unfit for production--but he also offers a dispassionate and technical explanation.
I love Obj-C and have eyed RubyMotion and other Ruby-related projects like it (MacRuby, etc.), and it is nice to hear from an unapologetic supporter of a project that it is not production ready, despite the hype and fanfare.
Thank you.
At some point, Borland disabused me of the notion that serious toolchain providers fixed their critical flaws promptly... or at all.
With which he means "a substitute", "a similar tech", "their own implementation of the same concept", "something analogous to ARC" (hence the "analog").
(Most people know "analog" only as in "analog vs digital", but it was immediately obvious to me, because I know the etymology of the word from the original language it was adopted from.
Btw, the english dictionary definition that's closer for such a use of the word is:
1. An organ or structure that is similar in function to one in another kind of organism but is of dissimilar evolutionary origin. The wings of birds and the wings of insects are analogs.).
Debatably, as is the subject of this article.
https://groups.google.com/d/msg/rubymotion/x6-9c__IHH0/J7jYd...
Ruby Motion is supposed to make iOS and Mac OS X app development simpler than Objective C. If there are lots of complex rules and corner cases to learn about and work around, it becomes easier to just write Objective C, where at least the rules about memory are well understood by the community.
Will be interesting to see how HipByte addresses this. They at least need to get in front of the issue with a blog entry or article about how they plan to address it.
And there have been successful bridges from Python/Ruby to Obj-C that had GC too.
Now, ARC, or something similar for RubyMotion, is a different take on the matter. I don't know why they want that way instead of an actual GC.
It's only complicated in Objective-C because of all the C.
(Looking at your web site, seems like you would have a good understanding of the underlying issues.)
As best I can tell from the article and the filed bug, it comes down to not retaining captured variables in blocks. In Objective-C, there's some automatic memory management that happens for you when you capture a variable in a block:
id x = ...;
^{ NSLog(@"%@", x); };
Because the block depends on x, the lifetime of that object needs to be tied to the lifetime of the block. As such, the compiler emits code so that if and when you copy the block onto the heap, it automatically retains x. When the block object is destroyed, it automatically releases x.Note that, while definitely "automatic reference counting", this isn't, strictly speaking, ARC. Because this is so critical to being able to use blocks without going completely insane, this bit of cleverness was introduced with blocks on 10.6, even though ARC didn't exist yet.
The note in the bug says that it's complicated because they don't want to introduce a performance regression. This suggests that they're not having trouble with retaining objects referenced by the block per se, but rather with being smart about it, so that it's only retained when necessary. The Objective-C compiler does this by constructing blocks on the stack, and requiring an explicit copy to move them to the heap. Only when explicitly copied do they retain the variables they capture, so simple inline cases remain fast. Perhaps Ruby or RubyMotion have something that makes this harder to do.
If that's correct, then I can't say I find the excuse a very good one. Performance regressions are bad, but generating incorrect code is much worse. They need to fix it immediately, take the speed hit, then see about ways to improve performance while maintaining correctness. However, I certainly could be wrong.
The workaround now is just to create a class around each block operation. I've been thinking about this issue quite a bit (I intrigued many developers using RM are actually not observing this issue sooner) and this workaround seems to be the only way to use APIs like #beginBackgroundTaskWithExpirationHandler: and #endBackgroundTask: which has no non-block based alternatives and is always called asynchronously.
First, said workaround would completely change the entire structure of your ruby code. Basically, kill blocks. This is inferior to Objective-C itself structure-wise.
Second, and most importantly, this bug is not something that jumps out at you. It only causes crashes in some small % of runs. So, the result is your apps look fine, you are writing idiomatic ruby, but once you release to production, you start getting crash reports because you closed over a local variable that ends up being released. This is the kiss of death for production apps: un-reproducible bugs due to magic in the compiler not working as expected.
In other words, even if you know about the bug, and even if you understand the workaround, if you write code naturally, you are going to introduce crashing bugs that are not reproducible that affect some small but measurable percentage of your users. A true nightmare.
It is VERY relevant that there is a workaround. Additionally, it's kind of unfair to point at 1 bug (that has a workaround) and judge an entire system on it.
https://yourlogicalfallacyis.com/composition-division https://yourlogicalfallacyis.com/no-true-scotsman https://yourlogicalfallacyis.com/the-texas-sharpshooter
edit: Laurent (RubyMotion lead) has chimed in and raised the priority of this issue, this is great news