RubyMotion - Ruby for iOS
rubymotion.com
rubymotion.com
http://www.rubymotion.com/developer-center/guides/project-ma...
No XCode. Instead of obscure and impenetrable project files, a convention over configuration Rakefile. Clean and Ruby-like workflows and repositories.
While you can certainly configure an Xcode workspace to program in RubyMotion, we do not provide any support for Xcode out-of-the-box. We do not believe that Xcode makes a good environment for Ruby development (or development in general). Ruby also makes it very easy to write great Domain-Specific Languages that can be used as elegant alternatives to graphical user interface or data modeling tools. [1]
Laurent Sansonetti gets it. I've been writing iOS code for three years and have never been able to figure out how to have a frictionless workflow around XCode, everything about it is convoluted. The idea of automating frequent development tasks with Ruby generators and DSLs sounds exciting and promising.
I dabbled in Obj-C over the years and jumped on the iOS dev bandwagon as soon as the first SDK was available. It was a long journey and coming from Ruby, I was very resistant. Once you're used to succinct syntax, it's really hard to use something as wordy as Obj-C (this was the main reason I never went back to Java). But over the years I came to appreciate Obj-C. I loved the speed and I clearly knew mobile was gonna be the next real fun thing to work on.
And that's where I've been the past 4 years, iOS land. I'm pretty comfortable now with Obj-C and the iOS framework and have worked on a number of projects in the app store. I can really say that I've seen all levels of crappy to great code. But last night when I went thru the samples of the Ruby Motion stuff, I was a little flabbergasted. I'm (now) so used to XCode code completing long method names and when I saw the Ruby equivalent and how condensed everything was, it kinda blew my mind again. I found myself thinking "whoa, that's right, there's no interfaces" when looking at the accessors (omg, so much less code vs. using typical ivar properties) and just all these little Rubyisms that I'm not used to seeing with iOS. It totally made me smile. Oh yah and blocks! They're, like, readable again. :)
Anyway, just to play around with the examples (which are pretty decent) was worth the intro price for me (I can expense it anyway). One big thing that does not yet exist is IB support. A few years back I switched to IB 100% (when possible) and so I'd much rather lay out my ui vs. code it all up. I've included a good Ars link below and in it Sansonetti says they're coming out with a DSL for easily laying out the ui. That will be interesting and it could push me over the edge for using this on a real project. Time will tell.
I kinda feel like I felt the first time I saw Rails. I would recommend anyone remotely interested just check out the Github demos.
http://arstechnica.com/business/news/2012/05/exclusive-build...
http://www.rubymotion.com/features/
at the bottom of the page:
RubyMotion is based on MacRuby, a widely-used implementation of Ruby created and maintained by Apple for over 4 years. Starting from a solid and stable code base, the guys who originally created MacRuby now work on RubyMotion. You're in good hands.
This will let you, as a developer, try and learn to use RubyMotion before you actually buy a license.
A question for the developers - did you consider this option and reject it for some reason?
The problem with Rubyists (being one for the past 6 years I feel qualified to say this) is in general they want to use Ruby for everything. It's not always the best tool for the job.
This is generally true of the Java community as well. There was a solid decade where there was a jSomethingOrOther for everything in development.
As for your second paragraph, you can say that about any '-ists'. I've met java, python and .Net people who all love their respective languages and just want to code in that. To me, Rubyists aren't better or worse in that respect.
Interestingly, from my point of view, Obj-C made perfect sense to me when I realized that it was basically Ruby with C syntax. Given the heritage of Ruby and Obj-C, they come out as very similar languages, so I found it a breeze to pick up the other.
The hard part was learning the Cocoa (Touch) frameworks, but I'm not sure a Ruby API would have made that any easier. It's simply a massive amount of information to take in all at once.
For example, in using the RubyMotion beta, after I understood the UIView animation flow, I created a helper method using "yield" to do the actual animation. If I were working in Obj-C, it would've been a lot more work to do the equivalent (and I probably would've just copy-pasted existing code around instead).
def animate
UIView.begin_animation
yield
UIView.commit_animation
end
animate do
# Do something
end
and: void animate(void (^block)(void))
{
[UIView beginAnimation];
block();
[UIView commitAnimation];
}
animate(^ {
// Do something
});
Which to my eye are pretty much exactly the same. In fact, UIView already provides a similar method built into the API.Anyway, I don't want to diminish what you've accomplished. It's an awesome achievement regardless of the language you choose.
Yeah, it's actually much, much simpler to do it in Objective-C in this case.
[UIView animateWithDuration:0.5f animations:^{
// Do something
}];UIView.animateWithDuration(0.5, animations:lambda { //do something })
in RubyMotion. Basically the same.
def animate(*args)
UIView.begin_animation
yield(*args)
UIView.commit_animation
end
animate(myButton, &buttonAnimateBlockFromSomewhereElse)
animate(myView, myOtherView, &genericAnimateBlockFromSomewhereElseWithTwoArgs)
animate do
# Do something locally ignoring args
end
And, yes, you can do the same thing with Obj-C and some creative casts...but it's nicer in RubyMotion! (ymmv) [UIView animateWithDuration:1.0f
animations:^{
self.view.alpha=0.0f;
}];
Not so hard.I think I'll try and write up a demo app to explain what I mean...
I think you are over thinking things.
void animate(void (^block)(va_list), ...)
{
va_list args;
va_start(args, block);
block(args);
va_end(args);
}
void (^first)(va_list) = ^(va_list args) {
NSLog(@"%@", va_arg(args, id));
};
void (^second)(va_list) = ^(va_list args) {
NSLog(@"%@", va_arg(args, id));
NSLog(@"%@", va_arg(args, id));
};
animate(first, @"Hello World");
animate(second, @"Hello", [[NSNumber alloc] initWithInt:10]);
I would like to see the real-world code too. The frameworks in question revolve around Obj-C-isms, so to see something that completely deviates from those patterns will be interesting.Yeah, well, you know, that's just, like, your opinion, man.
I've been using Ruby to create pleasant to use APIs around more complicated (native) APIs in both Java and .Net and it has always been a very big win in my situations.
I just bought a RubyMotion license and can see it going very far :)
Well… why not?
This is a relatively objective statement; the problem with ruby tends to be the crappy interpreter we're forced to suffer through - not the language itself. The Ruby language, in my biased opinion, as far as OO-functional languages go is pure awesome.
My initial reaction was: "A Ruby to Obj-C ABI compiler? Fuck no, what is wrong with you."
Upon learning it was the MacRuby dude: "Holy shit fuck yes".
I really don't want to ditch my entire development workflow to pick up Xcode, and Objective C, and miss out on all of the development libraries and vibrant community that I already have access to.
The problem with company led development environments is that they're tailored to the vendor's, and not the community's, needs. Development is rigid and low on innovation.
If this framework is half as good as it seems to be, within a month we'll see a dozen libraries that abstract all sorts of pain away from iOS development. Abstracting the pain away is something the Ruby community tends to do well.
I've gone from being totally uninterested in iOS development to being excited in what I can do inside UIWebviews. Naive, maybe, but it's probably significantly lowered the amount of investment I have to make into creating an iOS app.
Couldn't have said it better myself.
Learning is hard, and doubly so when you're in your comfort zone. You can deride that and make it about a person's "toughness" as a programmer, or you can think about exactly how much time it takes to learn a language and its idioms, highlights, lowlights, problems, and features.
A person who's really good at C# or Java is not going to be really good at Obj-C without losing a significant amount of time. That's why these kinds of projects appear. There's only so much time in the day to learn a new language well. :)
As an Objective-C programmer myself, I was initially really turned off by this attitude from the JavaScript community: (Why do we need we need a LISP implementation in JS? It's already a functional language! Why do we need Objective-J? JS already kind of has classes!). Hilariously enough, the only language that was "accepted" by the JS community was the one that specifically promised that it wouldn't add any new features: CoffeeScript. I missed the Objective-C community precisely because I had always found it quite unreligious and practical: to each his own when it comes to development -- I hope that with its latest success it hasn't become more dogmatic and insular.
We already have -- and without great fanfare -- Lua, JavaScript, C# (MonoTouch), et al. This seems somehow different.
Douchebags are everywhere and it's sort of silly to paint an entire community with a broad brush. We're doing lots of good things, too, despite our own share of jerks.
Culture aside, simply technologically, Ruby has nothing significant to offer as compared to the many existing languages and technology stacks, especially those pushing forward language and runtime research. The only argument for Ruby here seems to be opening the market to developers unwilling to move beyond it.
- Despite the opinion clearly being unpopular here, I stand by it: the ruby community is toxic-at-best, and totally technogically uninteresting.
Individual Ruby developers may be very nice people, but that doesn't make the technology any more notable or novel, and doesn't change the general tenor of the Ruby community, which seems to be driven by larger than life personalities and a general lack of solid applied computer science.
But I also want to respond to the somewhat more interesting portions of your argument - is ruby "technically interesting", "notable", "novel", and/or lacking in "solid applied computer science", and to what extent do those things matter? I think it is technically interesting because you can do much with little, notable because it combines the elegant OO of Smalltalk and the weak functional programming of Lisp with an intuitive syntax reminiscent of though dissimilar to Python, not at all novel because it prefers to embrace good ideas from its predecessors, and quite thankfully lacking in leakage of hard computer science into mundane programs. It is wrong for many jobs, but right for many others, and for that it is interesting. It is one of a multitude of languages for which the same can be said.
2) Pure command-line interface that works with text files, that makes it work easily with any toolchain. Seems that GNU Smalltalk is the first version which only recently did not require an IDE.
3) All the basic and most useful objects are literals. Enumerators are stupid-easy to use.
4) Much lower learning curve than Smalltalk.
5) Adopts some useful Perlisms into the language mix.
6) A large focus on unit testing, and TDD. And they are very easy to use.
Programming is becoming a huge part of everyone's lives. Languages that ease the learning of CS and lower the barriers to entry are very welcome. And some of them also happen to be great business tools.
I don't think many here are arguing that Ruby is particularly interesting technology-wise. Amongst languages, well, it isn't particularly. But the baseless FUD about the "culture" or the "community" is unnecessary.
Its driven from the top, largely because most mature programmers that would provide a counter to community immaturity have no reason or need to use Ruby.
Things like "the [whatever] community is toxic-at-best" or "I don't relish the notion of [whatever] culture" are opinions that in Ruby's case are based on the behavior of a minority. It's like if people say all C developers are "fat bearded men." Quite a few are, but it's an unhelpful generalization.
If the Ruby community had a general atmosphere or a policy of encouraging sexist or unprofessional behavior, I'd let these remarks slide. But it doesn't. The articles and rants that make it to HN are usually the controversial parts because that's more likely to get votes on social voting sites like HN, alas.
And unsurprisingly, Linux is a terrible overall example of quality kernel development and design.
> If the Ruby community had a general atmosphere or a policy of encouraging sexist or unprofessional behavior, I'd let these remarks slide. But it doesn't.
Except that the only times I've ever had to deal with (or hear of, third-hand) a general atmosphere of sexist, unprofessional behavior in technology has been in relation to the startup community in general, and the Ruby community in particular.
You just described the majority of Ruby coders I've ever worked with. (mentally scrolls work history roster of Ruby devs...)
Yeah, in fact you've just described all of them.
I'm sorry your sampling of Ruby coders has been so poor, and I'm sure you could present examples to defend your prejudice. I know the stereotype you're talking about. I haven't worked with one of them, but I know they're out there.
Nevertheless, it seems to me you've become the thing you claim to despise: insular and closed off to experiences that would contradict your dogmas.
> Nevertheless, it seems to me you've become the thing you claim to despise: insular and closed off to experiences that would contradict your dogmas.
That would be the opposite of "polyglot". I can find value in Clojure's concurrency design, Python's scientific community, Scala's marriage of OO and functional, F#'s modernization of ML environments, C#'s language design, ObjC's UIKit/AppKit libraries, C's propensity for close-to-the-metal optimization without dropping to assembly, Haskell's lazy evaluation and functional purity, OCaml's mixture of pure functional with mutable state, Erlang's micro-thread actors, Java's virtual machine, Smalltalk's REPL-on-steroids, lua's JIT.
However, almost nothing from Ruby. The technology there is almost totally uninteresting -- it's just yet another imperative scripting language with a poorly designed runtime -- and the community, unlike Python's, doesn't make up for it. In fact, that Ruby community is one of the primary things that seems to give technologists a bad name outside the technology industry. When I hear tales of sexist conference behavior, inappropriate language in presentations, and outright bad wheel-reinventing technology, the tales are almost always tied to either Ruby, youthful startups, or both.
So -- no, I don't look forward to them joining the rest of us in the iOS space.
Again, I'm sorry your poor sampling seems to have traumatized you into an an irrational, confirmation-bias myopia, but my experience has been very different.
You like C#'s language design? Me too. I especially like its adoption of Ruby-ish idioms like lambdas and the LINQ collections DSL, and the C#-on-Rails framework goodness of ASP MVC.
"it's just yet another imperative scripting language with a poorly designed runtime"
Sweet Lord what an ignorant statement.
Here's the thing that Ruby does astonishingly well that none of those others you mentioned can do: metaprogramming. None of the languages can touch Ruby for its ability to consolidate expressive, DSL-like idioms that eliminate code duplication (and therefore bugs), increase communication and application logic clarity. This is where Ruby really eclipses everybody else, in its ability to create frameworks, DSLs and micro-solutions that drive interesting and expressive conventions that drastically reduces the time it takes to code and deliver a feature out the door.
This is why frameworks like Rails and Sinatra have been so successful with polyglot programmers like the ones I work with, and why new frameworks like Merb and Padrino keep popping up and offer new idioms and expressive possibilities. It's just a creative, open language to work with, that allows a creativity and level of surprising possibilities that have real business consequences. At the application level, where code conciseness and time-to-delivery are at a premium, Ruby simply shines.
You mention LINQ as somehow deriving from Ruby -- it doesn't, it derives from set theory, relational algebra, and some very careful consideration of how to model those in a typesafe environment. You fail to mention that LINQ is type-safe, which is an enormous advantage to its use compared to traditional approaches of modeling set theory / relational data problems, and has value for things well beyond databases or querying simple data structures, eg: http://msdn.microsoft.com/en-us/data/gg577609
You claim lambdas as Ruby-ish idioms, and yet totally ignore where "lambda" derives from: lambda calculus. This is not a Ruby-ism, and Ruby discards much of what is of value in lambda calculus: http://en.wikipedia.org/wiki/Lambda_calculus#Lambda_calculus...
Ruby is a "me too" on those fronts, and not a particularly novel one.
Of course. No one, especially not Matz, ever claimed Ruby was novel. Why should I care whether a language feature is new when I have features to ship? What you seem to be dogmatically, blindly ignoring is that Ruby's peculiar amalgamation of existing techniques, borrowed from (standing on the shoulders of) Smalltalk, Perl, Python, certain aspects of Lisp and others, created an expressiveness with those idioms that invited widespread adoption that Smalltalk and Lisp in all their glory only ever dreamed of. Innovation was the least of Ruby's concerns, and it's irrelevant to the conversation at hand.
Type-safety seems to be a big thing for you. This may seem to be an enormous advantage to you, and I wish you well. I personally think type safety is the most overrated language feature in CS history. In my crankier moments I'd say it's essentially a compile-time unit test and refactoring/code-browsing crutch for IDE-jockeys that don't test their code. In my less-cranky moments...I'll probably say the same thing. And that's after a decade and an half in Java and C#, not quite a decade in Ruby. To me, type safety imposes far more overhead than it's worth -- generics, abstract classes, interfaces, all irrelevant and basically built-in and implicit in dynamic environments like Ruby. But that's another digression. Suffice it to say, in my entire software career I've kept track of the sum total of bugs I've fixed related to passing the wrong type to a method, or receiving a wrong type from a method, and that number, to date, is (whirring, calculating sounds): 0. Total number of times I wished I had a refactoring shortcut for "extract interface", "rename method", "introduce parameter object" in a Ruby environment: 0.
I've not written a line of Scala or F#, so I can't speak to those, but the notion that C# could construct a DSL a fraction as concise and expressive as Ruby could is absurd. I like C# quite a bit, but let's not be ridiculous.
And I never claimed that LINQ or C# lambdas were derived from Ruby, just that they were Ruby-ish. Clearly someone in Redmond is watching Ruby and Rails. ASP MVC directly borrows Rails idioms, and many aspects of LINQ seem to have at least had Ruby in view, like 'Select', etc., even down to using hashrockets, although in a different manner. I certainly wouldn't be the first to point these parallels out:
http://nerdfortress.com/2008/06/12/c-30-encourages-rubyisms/
http://haacked.com/archive/2007/05/24/ruby-like-syntax-in-c-...
http://blog.troyd.net/PermaLink,guid,c4d8233b-77f4-4660-91a9...
http://rubysource.com/c-dynamic-features-helped-me-learn-rub...
This is the classic response. It's also ridiculous. It's not just a matter of "passing the wrong type", it's a matter of using the type system to express higher-level constraints that make it impossible to introduce bugs in a complex system -- bugs more fancy than "I passed a string when I should have passed an int".
Of course, passing a string when you should have passed an int happens with regularity, too, and claims otherwise are a lie, especially if you don't spend a ridiculous amount of time pretending to be a compiler by writing extensive unit tests that would be totally unnecessary if you had one.
> And I never claimed that LINQ or C# lambdas were derived from Ruby, just that they were Ruby-ish. Clearly someone in Redmond is watching Ruby and Rails.
What? I ... no. I point out a 1965 paper on lambdas and you claim MS R&D is watching Ruby? You're comparing LINQ -- which implements a coherent model of relational algebra and set theory -- to Rails?
Ruby didn't pioneer these things, didn't add anything novel to them, implemented inconsistent models of them, and can't take any credit for them.
It's classic because it's true.
"bugs more fancy..."
Fancy? Fancy?? (thumbs through Knuth and SICP looking for "fancy" bugs...looks for "fancy" anti-pattern...)
Nope, not there. Consistent with my own experience, rather than anecdotal FUD (Fanciness Uncertainty and Doubt), after years and years and thousands and thousands of lines of code in type-safe and dynamic environments, I've yet to encounter a significant issue that would have been caught by a type-safe system.
"...especially if you don't spend a ridiculous amount of time pretending to be a compiler by writing extensive unit tests that would be totally unnecessary if you had one."
Complete. Nonsense. I write the same unit tests in RSpec and TestUnit that I write in NUnit and JUnit, and far, far, FAR, fewer lines of code for the same coverage in Ruby. I do NOT write extra unit tests because -- holy crap! I don't have type-safety!
No, type coverage is a side-effect of a well-written unit test. No extra effort whatsoever is needed.
"I point out a 1965 paper on lambdas and you claim MS R&D is watching Ruby?"
This is starting to sound like a debate between a CS student who just got out of a Set Theory final and just figured out who CAR Hoare is, and someone who is just trying to ship features and make sure his company makes money. Yes, I have a decent handle on lambda calculus (thanks for the Wikipedia link) and I know the differences between Ruby's collections DSL and LINQ, having used both pretty extensively.
It doesn't matter. The notion that MS is not paying attention to the most influential application framework of the last 10 years is a ridiculous idea. The fact that Ruby didn't pioneer lambda calculus is...just as obvious as the fact that C# didn't pioneer VMs, GC, generics, etc., and can't take credit for those either, and just as much of a non-sequitur.
I'm afraid this might come down to a philosophical difference for you.
That's funny, because to me it seems you've taken a few of them at their word about what "the Ruby community" is like (or even the existence of a singular one in the first place).
As I'm sure you've seen, even Objective-C is too slow for many things when developing for iOS - for instance, if you want to get halfway decent UITableView performance it's best to write a custom UIView where instead of laying out nested subviews, you drop into C and do all your layout in drawRect using only CoreGraphics API calls.
If you're attempting to do anything more complicated than hooking together pre-fab components, your performance is probably going to suck if your views are written in Ruby. And it's the silky smooth graphics people have come to expect that give iOS the reputation it's earned for slick UI.
It doesn't mean you shouldn't necessarily use a framework like this, but you don't get all that convenience for free. I've often felt that the reason Objective-C remains in use (aside from the fact that it's kept alive by Apple) is that it sits in a really practical middle ground between the bare metal performance of C and the convenience (and tradeoffs) of "nicer" languages. As I said above, though, this is just my default reaction, and I'd love to see this stuff in action if it's truly usable for a reasonable subset of use cases.
Also, Objective-C is not the slow bit in the example you described. There is a lot of logic overhead in laying out views in Cocoa. While it's true Objective-C (the language) may have some overhead, it's not much. And it's certainly not anything compared to laying out a complex view tree.
As for Objective-C, whether the language in and of itself is the source of the slowness I was talking about is somewhat beside the point, IMHO. I'm aware that laying out views in Cocoa involves a lot of overhead, and that it's as much to do with the complexity of what's going on under the hood as anything. The fact of the matter remains though that you take a performance hit when laying out non-trivial views that need to be updated as fast as possible (e.g. when a table view scrolls by even one pixel and all the views have to be redrawn). You could probably convince me that Objective-C isn't the reason this is the case, but in any event, when you find the need to drop down into direct drawing API calls in order to get the performance you need, the "not much" overhead you're talking about can become much more noticeable. In a tight loop, a factor of 2 can make a huge difference, even though "2x slower than C" would be an enviable benchmark for many languages.
Again, I'm certainly not denigrating Ruby or other languages, but to me, that aspect of iOS development is a reminder that one needs to choose tools carefully for the job at hand. Hence my hesitation at the announcement of alternative toolkits for iOS apps, the vast majority of which I have yet to see any stellar examples of. Here's hoping this will break the mold.
Not true, on a bunch of different levels.
A. Go do a benchmark with a nib loaded with UINib, and then with your "non-trivial view". The difference is negligible. You won't get more than 1-2 fps more by keeping it in code. And honestly? If you're that desperate for 1-2 fps, you're not likely bottlenecked at drawing code.
B. If you scroll by one pixel, at most, you'll have one new cell to redraw: the one that appeared on screen at the end. You don't redraw everything all the time.
C. I find that custom code is usually slower than loading some images and placing them on screen. CoreGraphics functions, for example, don't use the GPU. Set the wrong property on your layer (try touching CALayer's shadow properties on a large scrollview)? You lose ~20FPS. GPU is too busy calculating stuff to actually put stuff on screen, so CA drops frame.
A. I wasn't talking about loading a nib vs programmatically wiring up a view. Many people never touch interface builder and write all their views from scratch, but in that case you still have the choice between compositing your view using subviews and overriding drawRect with drawing calls. Have you ever has the pleasure setting up a tableview controller on an older (first or second generation) iOS device? The difference in responsiveness there can be quite striking. This may be a topic rendered somewhat moot with newer hardware.
B. That's not my understanding, but if you have a source on that I'd appreciate a link. I was under the impression that while the cell will only be requested once it comes into view, scrolling the table still requires the visible to cells to be re-layed out, which is where the relative inefficiency of subview rendering starts to hurt you. I certainly could be wrong about that though.
C. If I recall, CoreGraphics is implemented on top of OpenGL. You still don't want to do complex graphics in your cell's drawRect in this sort of situation (I'm just imagining an image and a few labels, nothing fancy). Drawing a static image, pre-generated or cached, is a nice solution in some cases.
Many people overestimate how expensive a view is to lay out, and jump straight into code (I'm as guilty of this as anyone else), without actually stopping to see how nibs perform, due to misunderstanding some part of the pipeline.
Have you ever has the pleasure setting up a tableview controller on an older (first or second generation) iOS device? The difference in responsiveness there can be quite striking. This may be a topic rendered somewhat moot with newer hardware.
Yup. Fun times. Glad we're not there anymore. And given AT&T gives away 3GS's for free, I'd have to agree that the topic's moot and go on to say that it isn't worth the time or effort to support a device that no one has anymore ;)
..but if you have a source on that I'd appreciate a link
Add a log to -layoutSubviews of your cell subclass, and look at how often it gets printed out when you scroll.
If I recall, CoreGraphics is implemented on top of OpenGL. You still don't want to do complex graphics in your cell's drawRect in this sort of situation (I'm just imagining an image and a few labels, nothing fancy). Drawing a static image, pre-generated or cached, is a nice solution in some cases.
Go far enough back, and everything UI-related is OpenGL. CoreGraphics, however, is not built directly on top of OpenGL. It's part of Quartz, (specifically, QuartzGL). QGL on Mac can use either CPU-backed or GPU-backed drawing. On Mac, QGL defaults to CPU-backed drawing, but an app can use the GPU backing instead, by setting QuartzGLEnable to true in Info.plist. This option isn't available on iOS. You're stuck with CPU, only, for CG.
Objective-C's heritage as a strict superset of C means that, ultimately, it's syntax is limited (why do you think all the new literal forms are prefixed with "@"). Ruby, on the other hand, excelles at constructing DSLs.
I think you'll find that this strength of Ruby will make RubyMotion a compelling solution for a wide range of tasks in iOS development. That said, CocoaPod support is built in, so you really can have the best of both worlds.
Anecdote: When ARC was first released, I decided to turn it on for a small project. The very first method I wrote blew up with a memory error. The reason? I used the NSFontMatrixAttribute of NSFontDescriptor. For some reason, ARC doesn't handle it correctly. I've never had such a thing happen in Ruby.
There is still a long way to go from where Objective-C is. It's moving in the right direction, but there's still a long road ahead of it. Ruby is closer to being there, though the lack of tool support (particularly autocomplete) makes it a much less compelling proposition than it would otherwise be.
Also, Ruby can be considerably easier than Objective-C to read because there is a lot less line noise. Objective-C's method names read very smoothly out loud, but they can also be visually overwhelming at times and make code sort of melt together into a wall of text. It's maybe a little bit easier to read Objective-C quickly when you're being very deliberate about it, but it's much easier to skim Ruby in my experience.
I probably won't be using this, and I think your criticism of Rubyists is kind of valid, but I think — for this particular project — you're dismissing it too readily.
Actually, I can say the same regarding Java/Android API correlation.
Not to denigrate you or your statement, and yes Objective-C is not that hard to learn, but it comes down to speed.
If I've never programmed in Objective-C and if I'm experienced in Ruby my time from concept to live iPhone app can be FAR quicker by using the tools/language I'm already familiar with (regardless of which tools/language).
Remove the concept of learning a new language, a new IDE, and only require that I learn a new lib to work against and I'm FAR quicker.
Yes, there may be some limitations. But this is iterative development. Build something as solid and quick as possible, and give users the chance to play with it. If it works, and you need more flexibility, it's reasonable to spend the time on learning new tools/languages.
You are right :).
Just for reference, yes I code in both Objective-C AND Ruby.
There are significant speed gains when using the tools/language you're most familiar with. I've seen this first hand with myself, and in others... It's not about "how easy it is to learn" it's about "how much time it takes."
You're mixing together two entirely different topics.
> Remove the concept of learning a new language, a new IDE, and only require that I learn a new lib to work against and I'm FAR quicker.
That's a bit like saying, "Remove the concept of putting on running shoes and warming up and only require that I run a marathon and I'm FAR quicker." The time to tie your shoes is nothing compared to running the marathon. Likewise, the trouble of learning Objective-C (especially with a background in Ruby) is insignificant compared to the time it takes to learn Cocoa.
It's not at all like saying that. Feel free to keep your words out of my mouth :)
> ...is insignificant compared to the time it takes to learn Cocoa.
I see you've changed from using the word "easy" to the word "learn." That's a step in the right direction :)
Though, we are not comparing the time it takes to learn Cocoa vs. Objective-C. That was NOT the crux of my comment. Again, you're missing the point (you seem to be very talented at this).
The comparison is with Ruby ;)
You're just on the defensive, so it feels like hostility. It's understandable...
> My point is that if you did make the comparison...
But I didn't.
I never compared the two.
My statement was one of a speed gain by simply using the languages/tools you're most familiar with, instead of learning new languages/tools.
It cuts out a lot of time, it's not a hard concept to understand ;)
> You're just on the defensive, so it feels like hostility. It's understandable...
Really, no. I don't know if it's intentional or not, but you come across as very passive-aggressive and condescending. I don't even know what it is I'm supposed to be "on the defensive" about — the fact that learning Objective-C takes much less time than learning Cocoa? I feel pretty secure in that knowledge.
> But I didn't.
> I never compared the two.
Yes, that is my point — your opinion has no sense of scale, because you haven't compared the two. You're talking about saving pennies on the price of a sports car. I just don't think it's a particularly pressing concern. If you're that worried about pennies, you're probably not in a position to buy that car.
But, you know, whatever works for you.
For example, consider using regular expressions in Ruby to check a string -
puts "The limits of my language define the limits of my world" if string =~ /foobar(\d*\w)/
or in Objective C: NSError *error = NULL;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"foobar(\\d*\\w)"
options:NSRegularExpressionCaseInsensitive error:&error];
NSTextCheckingResult *match = [regex firstMatchInString:string
options:0
range:NSMakeRange(0, [string length])];
if (match) {
NSLog(@"The limits of my language define the limits of my world - Wittgenstein")
}
Until quite recently it wasn't even possible to do this in ObjC without an external library.Actually, I think your code examples support my point. You're not contrasting Ruby and Objective-C, you're contrasting Ruby's standard library with the Objective-C library Foundation, which is what you need to learn to get any real use out of MacRuby/RubyMotion. Here's the MacRuby/Cocoa version of that code:
error = Pointer.new_with_type '@'
regex = NSRegularExpression.regularExpressionWithPattern("foobar(\\d*\\w)", options: NSRegularExpressionCaseInsensitive error: error)
match = regex.firstMatchInString(string, options: 0, range: NSMakeRange(0, string.length))
NSLog "The limits of my language define the limits of my world - Wittgenstein" if match
Do you really feel that Objective-C is the biggest difference between the three examples?BTW, if it sounds like I'm trying to say RubyMotion is pointless, I'm not. I'm just saying that "I don't want to go to the trouble of learning Objective-C" is a weak reason to use RubyMotion, because you'll have to do 99.95% of the same work anyway.
The example was supposed to illustrate that some things are easier and more concise in ruby, and thus also presumably in something like Rubymotion. The relevance to your posts is that you are ignoring some very good reasons to use ruby in your focus on the cocoa api - not all programming in ios consists of calls to the api so learning it is not the only thing required to make an iPhone app. In some apps api calls might make up half of the code, with the rest being back-end stuff. Evidently Rubymotion does not mean you can avoid learning the api, it just helps you write the rest of your code in a preferred language while painlessly calling the apis to show stuff on the screen. Not having to deal with Xcode would be a bonus too.
> "I don't want to go to the trouble of learning Objective-C" is a weak reason to use RubyMotion, because you'll have to do 99.95% of the same work anyway.
The fact that Ruby can express things very concisely has nothing to do with whether or not learning Objective-C adds an appreciable amount to time to the process of learning Cocoa. That's why I was ignoring it. If you simply like Ruby on its own merits, that's a good reason to use it.
Here's the disconnect. That was never my point.
Please re-read my initial comment. You responded to that comment, hence you're responding to my initial point, which has nothing to do with your argument.
Do you get it?
The problem is your just not able to express your point, clearly, in relation to the context of this topic. Maybe face-to-face, verbally, you'd do a brilliant job of it. But in the written form, well... Not so good.
A little humility on your part would go a long way. Just saying ;)
RubyMotion doesn't just slap on a Ruby syntax, its objects inherit from both Ruby and Objective-C classes with some mixed in Ruby modules.
The RubyMotion development environment is, in my opinion, an improvement over XCode. And of course, there's the REPL.
The "awkward hack" you mentioned is nothing. I don't particularly like the way he's implemented pointers to pointers, but that's also minor. The benefits, for me, easily outweigh the negatives.
I feel the same way. I'm far more comfortable, and have far more trigger time on one language over another, and those inherent nuances make me far more productive.
Of course it's easy enough to learn a new language/library, but that's not the point. The point is what do I know now, and what can I be productive in, the quickest.
Kudos.
It's not a big deal*
* former smalltalker
This is a step in the right direction, a step toward getting immediate and interactive results when you code.
The piece that I find a tiny bit lacking is disconnect between what you futz with in the REPL and what is your source. By that I mean, all the manual tinkering in the REPL isn't saved anywhere, you have to copy and paste.
Emacs rectifies this sort of thing a little with swank and slime. Maybe there will be a mode for RubyMotion.
Sure, it's not hard to learn. But in my spare time, am I really going to work with a language I can't stand to make my iPhone app or am I just going to want to make a web app in Ruby? The latter sounds a lot more fun, but the former is obviously more efficient. The fact that we can now combine both? Holy shit.
Sure if you're writing the unreal engine it's not going to be the best idea, but it should do fine for a Facebook/Three20 type app.
Ruby skills: applicable across a very broad range of computing devices. Objective-C: not so much.
> Because RubyMotion implements a dialect of Ruby that is statically compiled, regular Ruby gems will not work in RubyMotion. We provide documentation which describes how to architect gems to work with RubyMotion.
I can see where this could be a problem if you typically just glue gems together to make products, but if you're used to rolling your own solutions it isn't a big deal.
Sucks, but not a show stopper.
This looks promising but at the same time I really wish the backend compiler was open sourced and worked on Mac and not just iOS.
http://lists.macosforge.org/pipermail/macruby-devel/2012-Apr...
"Our memory model, similar to Objective-C ARC in design, does not require any extra memory or processor footprint to allocate and reclaim unused objects"
1) http://arstechnica.com/business/news/2012/05/exclusive-build... (Review with code)
2) http://pragmaticstudio.com/screencasts/rubymotion (Screencast)
edit: also, please stop the heavy breathing into the mic. Driving me crazy!! :)
In particular, for those looking for a side-by-side comparison of what it means to use Ruby instead of Obj-C, be sure to check out the GestureTable sample: https://github.com/HipByte/RubyMotionSamples/tree/master/Ges... which was based on the JTGestureBasdeTableView: https://github.com/mystcolor/JTGestureBasedTableViewDemo
pretty much the same as an Objective-C app? Anyone have any clue as to why they didn't state apps in the two languages would look identical?
UI is a finicky thing, but assuming this allows you to use all Apple APIs, there is no reason you couldn't get an identical-looking UI using this.
You're right though, there's no reason the UI wouldn't look identical as well.
I can't express properly how awesome it is, really.
i.e. [obj method: param second: param2]; vs obj.method(param, second: param2) which is exactly two characters shorter in ruby.
And what would be the point of having something that looks like Objective-C?
UIColor.colorWithRed(red/100.0, green:green/100.0, blue:blue/100.0, alpha:1.0)
vs [UIColor colorWithRed:red/100.0 green:green/100.0 blue:blue/100.0 alpha:1.0];
>And what would be the point of having something that looks like Objective-C?Because the name of the function is not colorWithRed(), it is colorWithRed:blue:green:alpha:.
In the Ruby version I wouldn't use that selector with any parens. The resulting line would be one character longer than the ObjC version but use the Shift key one less time and would avoid two pinky trips out to the square brackets. (unless I am miscounting)
All other things being equal between the two options, and of course they aren't but let's just keep splitting hairs for a moment, it sounds like a typing win for the Ruby option. Readability is of course in the eye of the beholder.
In practice, how big a problem is that?
That may have changed tough because I dropped the xib as I didn't really needed it.
I would liken it to not using HTML when you're making a web app and you can only use javascript to generate (by hand) all of the UI.
In both cases, there are border cases that need to be handled in code (or markup).
I bet they are working on it, though...
If you have a good background in C than yes, using Objective-C is not so difficult.
This is a very exciting (and very positive) development, but at this moment in time I would still bite the bullet with Objective-C. I came to it with a background in PHP of all things and didn't struggle with picking it up in a few weeks.
I can't wait to see the things people do with it and with Ruby's metaprogramming.
I hope for the day when we have better and more type safe languages for system programming.
Most attempts so far, Modula-* family, Ada, Oberon and so on, failed to catch on, to my dismay.
Still it does not hurt to know some C.
I did some looking, and I found a few[1] examples[2] of coroutines in Objective-C, though none of them seemed fully fleshed-out. Even if they were, none were, as you say, nearly as nice as "yield".
Header files are so 70's.
For me, I prefer working in Ruby. Some people don't. But I think this will probably spurn me to get more serious about writing more iPhone apps, and it should open the door for a few more people who work on Ruby-based apps to write their own simple iPhone apps rather than paying a consultant to do it for them.
I can use Ruby's nice facilities for external processes (e.g., "x = `ls`" to get a directory listing or "system('do_something')") or simple regular expressions (i.e., "'string' =~ /my_regex/" and friends vs. NSRegularExpression's verbose syntax). I'm not forced to use Cocoa's verbose API if it has a nice Ruby wrapper (and if it doesn't have one, I can make one).
https://github.com/HipByte/RubyMotionSamples/blob/master/Ges...
Is what 95% of the code in your app is going to look like and I don't really see what it's buying you. You're also throwing away all the type checking you'd get on essentially the same code in Obj-C.
I really like Ruby but I don't intend to use it for iOS apps.
For instance, built-in TestFlight rake task, or build and run on device/simulator. I'd love to borrow some of that for a CI build system (which for me is currently a large shell script that could be improved on).
I'm also very interested by the interactive REPL that can run code inside my application. LLDB is good, but falls short for me occasionally.
>RubyMotion is 100% compliant with Apple's App Store policies. Your code is compiled ahead-of-time, never interpreted, and you access the entire set of iOS public APIs. At the end, a RubyMotion app looks pretty much the same as an Objective-C app.
"Applications submitted to the App Store must conform to the Review Guidelines dictated by Apple. RubyMotion implements a dialect of Ruby that conforms to those rules. RubyMotion apps are fully compiled, do not download or interpret code and are using public iOS APIs through the exact same machinery as regular Objective-C apps."
But quite frankly, I can't afford it. I'm a college student living on $25/week for food - I can't justify spending 6 weeks of food on an experiment.
If I could try it out? If I could build my killer app first and know that it works? It wouldn't hurt as much, but $150 is still a lot of money.
Sometimes searching for an easy way out is a waste of time.
Isn't the issue with a lot of these "look Ma, no Objective-C" approaches in that there are always little nagging issues here and there?
I mean, Apple is constantly moving Objective-C/Xcode/iOS (notice I didn't say "forward"). Isn't it somewhat dangerous to adopt peripheral approaches for development rather than staying (suffering?) with the Apple-provided tools?
Now, if someone has an alternative IDE that truly allows me to record Xcode to a DVD and perform a ritual burning ceremony of said DVD...that would be something.
The real key to this is the REPL and interactivity between coding and the running app. Being able to edit bits of functionality and structure in the running app, and immediately see the results is AWESOME!
I am currently working on a project that uses a genetic solver and some fairly complex state machines driven by fairly involved databases. I can't possibly see how something like this could be made to be interactive in terms of the development process. Generally speaking you are writing a lot of code before you get to compile and see the results. And, personally, I don't have any issues with the compilation process.
What do you mean by "interactive"?
I find them really easy to follow.
"It's Ruby, you don't need to think about managing memory. Ever. RubyMotion will by itself release the objects you create when they are no longer needed. Our memory model, similar to Objective-C ARC in design, does not require any extra memory or processor footprint to allocate and reclaim unused objects."
So, basically, you're stuck with retain cycles right now. My bet is that they implement a way of marking weak references rather than becoming more intelligent than ARC.
Of course, I guess I'm use to not having to worry too much about memory, either ...
Weak references aren't a panacea. It's not that uncommon to have cycles where all edges are equally strong. Any social graph ...
I use use counts to collect those cycles. ARC doesn't let you use use counts, but you don't have to use ARC everywhere. You do have to access to the underlying use counts ... MacRuby should allow access to that (it's just a standard Cocoa call) as long as it doesn't keep stray retains around that screw up my count balances ...
And I think CoreData is the answer to problems like a social graph. It does its own specialized memory management. But you're right, it's awkward to have to think about it.
"The limits of my language define the limits of my world" if string =~ /foobar(\d\w)/#
Objective-C :
NSError *error = NULL;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"foobar(\\d*\\w)"
options:NSRegularExpressionCaseInsensitive error:&error];
NSTextCheckingResult *match = [regex firstMatchInString:string
options:0
range:NSMakeRange(0, [string length])];
if (match) {
NSLog(@"The limits of my language define the limits of my world - Wittgenstein")
}
Enough said?With the Canadian dollar currently worth about 1 cent more than the US, I'm surprised to see that there is a price difference at all.
Bad programmers have a tendency to move from language to language, blaming their tools for their lack of skill.
This stuff is exciting.
Some languages have constituent parts that I'd say are objectively bad. I'll argue all day that Objective-C's handling of nil is stupid beyond belief. Nil/Null itself is bad enough...
For a practical example of what this means, see the most recent sample code that was released for mobiruby: https://gist.github.com/2577620
With RubyMotion you get to roughly lay out your controls, and then you get to use the interactive interpreter for fine-grained adjustments. See around the 5:30 mark in the getting started video for an example.
But I assume it uses storyboards in the same way as ObjC, set it in the target and in the Info.plist, and it figures it out... it'd be nice to see it working though.
So this should be compatible with cocos2d right?
My worry is that it would take off so well that the ruby gem community could get fragmented into libraries for RubyMotion and libraries for regular ruby projects.
This looks worth it just to have an XCode-free toolchain.
(main)>> require 'date'
=> #<RuntimeError: #require is not supported in RubyMotion>
(main)>> Date
=> #<NameError: uninitialized constant Date>That being said, it could be great, I have no idea.