6 ms·
Why I Like Ruby
- pbz 16y agoOne thing that puzzles me is the "expressiveness" factor. When I read code, in any language, I translate that code into blocks / models, not English. I don't read the code as I would read a book or an article. That would take too much effort / time because right after "reading" it, I would still have to parse it into the mental model. For me, if you write "if (myvariable != null) { }" or "unless(myvariable.nil?) end" doesn't make a difference. In fact, if I were to read it as English "if my variable is not null do" sounds better than "unless my variable is null, question mark?" -- I'm actually puzzled how you would "read" that. In any case, my argument is that a translation from code -> mental model is more efficient than code -> English -> mental model, in which case expressiveness is only helpful in as much as it helps in parsing the code and not "reading" it in English.
- joe_the_user 16y agoI find that display_warning() if problem_condition() feels much more expressive in some situations than if(problem_condition) display_warning() The later just emphasizes the primary activity to me - again, in some circumstances. It's something I miss now that I'm not doing Ruby anymore.
- mahmud 16y agoThat breaks efficient code reading. When you read code, you tend to skip through basic-blocks (i.e. consecutive statements without branches) and follow them to that intersection point where a decision has to be made. In traditional form, if you have: if (condition) consequence(); You're able to "run" the condition in your head and step into the consequence without loss of pace. But when you put the consequence before the condition, you will have to backtrack.
- v_ 16y agounless the consequence itself is something that signifies the end of a basic block, like a break or a next or a return.
- brianto2010 16y agobacktrack = true unless consequence.signifies? :block_end It doesn't seem that much harder to read.
- draegtun 16y agoUnfortunately though you are potentially adding subtle bugs here which can only be caught at run time. To avoid excessive test coverage it would be more pragmatic to do: backtrack = (consequence.signifies? :block_end) ? false : true But that's not as easy to read :(
- mahmud 16y agoI didn't reply to that one-liner because it is a one-liner. A lot of software engineering lore crumbles into tautologies or is completely obviated when you're working at the microscopic level.
- crayz 16y agoActually the ruby would just be "if myvariable" - I think it's more readable simply because it expresses the minimalist core of what that line of code is doing. I could also use Blub and say "IfConditionIsTrue(myVariable.booleanValueOfNullStatus())" Yes, you're right that my mental model of the 'if' construct will be basically the same in any language, but it's fundamentally less work and less error prone for me to translate ruby than some other language into that model, and the same is true going the other direction
- erikpukinskis 16y agoLet me just translate that post: include 'rspec' your_point.disagree do the_example.in_ruby = "if myvariable" me.think do this_thing(the_example.in_ruby).is(:more_readable) end.because do that_thing.expresses(the_example.in_ruby.what_its_doing.minimalist_core) end me.could do using "blub" do self.say "IfConditionIsTrue(myVariable.booleanValueOfNullStatus())" end end.implying do self.last_statement.is(:crazy_talk) end end your_point.agree do constructs = languages.map do |language| in language do me.mental_models.find_by_name("The If Construct") end end constructs.should be_identical end.with_caveat do languages.min do |language| in language do me.mental_models.find_all return me.mental_strain end end.should == "Ruby" end
- robconery 16y agoBrilliant! Except at the end... end.should be "Ruby"
- texel 16y agoThe given example of "unless myvariable.nil?" is a little bit awkard. In fact, the use of the "unless" keyword is, in my opinion, almost always awkward unless it's postfixed: "do_a_thing unless wait?" Not only that, but most of the time, the expression could simply be written "if myvariable; ...; end", seeing as the vast majority of the time, we only care if the thing we're testing is falsy. Ruby does give you the tools to be very expressive, indeed almost conversational in your coding style, but it also gives you enough rope to hang yourself.
- draegtun 16y agoDamian Conway in Perl Best Practices recommends not to use negative control statements at all (unless and until). So this would be a no-no: unless ($this > $that) { do_something(); } He's happy they're used to postfix statements however he says that these should only be used for flow control. For eg. for my $i (@list) { next unless $i % 2 == 0; do_something(); }
- draegtun 16y agoCorrection: Conway says don't use postfix unless, for, while or until So last example should be: for my $i (@list) { next if not $i % 2 == 0; do_something(); } Personally I don't follow the bible to the letter :) I do use prefix & postfix unless but only with simple truth conditions like this: unless ($this) { ... } next unless $this;
- GrandMasterBirt 16y agoExpressiveness is important. I remember many times reading logic and missing the little tinsy ! before a giant expression not making the quick flag in my mind raise indicating that this is a unless, not an if. In ruby the idea of the unless is not to save typing. In fact if !foo is easier to write than unless foo. However after a tad bit of getting used to it, you realize that it becomes immediately obvious when skimming the code what the operation is doing. The idea is lets leave the brainpower for the hard problems, and not require you to use all that brainpower to figure out the plumbing.
- erikpukinskis 16y agoPassing blocks is a much bigger deal to me in terms of expressiveness. Being able to pass around blocks lets you write APIs that are as powerful as language features. The new Routes API in Rails 3 is a great example of this: resources :people do resource :avatar member do get :republish_deep_links post :resend put :accessible_projects, :upload_preference end end That code sets up various URL paths in a Rails app. It maps URLs like /people/george/resend to the proper controller in the MVC framework. In many other languages, you could set up an API like this, but instead of taking a block, the "resources" function would have to accept some sort of nested data structure. That gets you pretty far, but what about when you want to do something that the parser of that data structure didn't expect? Usually you can't. But in Ruby, code is data and you can do whatever you want in those blocks. You could do this, for example: resources :people do resource :avatar member do ["apple", "orange", "peach"].each do |fruit| get "eat_" + fruit end end end That would map /people/george/eat_apple, /people/george/eat_orange, and /people/george/eat_peach. And maybe that's not that impressive to you, but you can inject arbitrary code in there. That's what people mean when they talk about expressiveness. Examples of this are everywhere in the Ruby world. Check out HAML and assert_select. APIs + Rigid data structures = Pain and suffering APIs + Ruby blocks = Flexibility and power
- erikpukinskis 16y agoI should say the first example I gave is from DHH's awesome presentation on his favorite Rails 3 features: http://www.youtube.com/watch?v=b0iKYRKtAsA http://www.youtube.com/watch?v=b0iKYRKtAsA
- deleted 16y ago[deleted]
- ecoffey 16y agoI skimmed part of this, and had to giggle a bit at this quote (of a quote): "It's clear that C# isn't the best language to use for Web Development. Just ask the guys who are writing the frameworks with it." Sure C# is verbose. But I still feel it's pretty expressive. I'm working on a web framework in C# (http://github.com/ecoffey/Bebop http://github.com/ecoffey/Bebop). Granted it's totally a toy thing, but still. Looks beautiful to me :-P Also it annoys me he compares non-idiomatic C# with idiomatic Ruby. I guess I should quote this FTA: "My whole point here is to tell you why I like it - not to convince you of anything.", and finish with it all comes back to the right tool for the job shrug.
- robconery 16y agoOK OK - edited: Rubyists are very stringent about syntax style, and there are styles WRT to C# but I'm not altogether aware of how you would accomplish the same things that I set out to do. Specifically: a null check.
- bhousel 16y agoPersonally I like the andand gem for this.. my_variable.andand.do_whatever
- joe_the_user 16y agoThe verbosity of both C# and Java just appall me. It would seem to me that verbosity and expressiveness are opposites - a language which inherently uses many lines to express an action is a language which inherently expresses little per line. How could it be otherwise?
- jasonlotito 16y agoI realize I'm going outside the context of the discussion here, but just wanted to comment on this. > a language which inherently uses many lines to express an action is a language which inherently expresses little per line Depends on what you an action is. It's nice working in a language where each thing does one thing and one thing only. A single line that does numerous things at once can get pretty crazy, with magical processes spreading pixie dust over your data.
- macuser1234 16y agoFor a web designer that works with css, html, and php, the only thing keeping me away is deployability. It seems that without learning git and the ways of my terminal, I have no way to make a web app with RoR. Not that I don't want to learn. I do, badly. But I just wish the barrier to entry could be lower. Either that or I just need to find a better tutorial going from nothing to a very simple app on Heroku and showing me how to experiment with it.
- michaelbuckbee 16y agoDeploying Rails has gotten significantly easier since the release of Passenger. It may not be quite as easy deploying PHP, but it's not far off.
- generalk 16y agoHaving done both PHP Zend Framework deployments, which require mod_rewrite rules in each vhost, and Passenger deployments, which only require touching a text file to do restarts, I much prefer Passenger deploys.
- jmahoney 16y agoWell, rails is opinionated software, and one of those opinions is that you should probably be familiar with a terminal.
- kiba 16y agohttp://railstutorial.org http://railstutorial.org is what I used to learn rails. It have information on how to use git and heroku too.
- jshen 16y agoYou don't have to use git if you don't use heroku. Passenger is an easy way to deploy rails code on your own.
- marknutter 16y agogo through the articles slicehost has written up to get rails and passenger installed and your app deployed. They are fantastic and you'll be very comfortable doing it anywhere else afterwards. http://articles.slicehost.com/rails http://articles.slicehost.com/rails
- RubyProgrammer 16y agoArticles like this should serve as a reminder of how indebted we are to DHH for creating Ruby and for inventing awesome language features like blocks, lambdas, and metaprogramming. Thanks, DHH! Without you, I and every other Ruby programmer would be stuck using Java or PHP (yuck).
- deleted 16y ago[deleted]
- msie 16y agoDHH invented Rails. Yukihiro Matsumoto invented Ruby.
- joe_the_user 16y agoAlso Al Gore!
- RubyProgrammer 16y agoWait, why was I downvoted? Ruby programmers, like me and the article's author, need to keep publicly praising Ruby at every chance we get until every non-Rubyist finally understands what an original, world-changing, end-of-history programming language Ruby really is.
- barrydahlberg 16y agoMy thoughts as someone who's been full time on C# for the last 5 or so years: Case 1 - His examples are toys, I don't think there's really an argument here. Better examples might convince. Case 2 - This is less about the language and more about the tools and the culture. The ecosystem in C# land is focused much more heavily in the business / enterprise direction which personally I hate. Point to Ruby. Case 3 - Half a point maybe. The .Net library is actually pretty good and each version of C# brings the language a step closer to the sort of concise code he shows. You can certainly get very close with a few wrappers here and there. Case 4 - Meta Programming, oh yes. 10 points to Ruby. It has been said elsewhere that C# doesn't have meta programming because it was designed to be predictable for whoever has to read it. In practice this seriously restricts our ability to express certain types of concepts that don't fit the basic OO model. Aspect oriented programming and mix-ins are the two currently frustrating me. We try to tackle this with all sorts of hacks (e.g. PostSharp, mangling .dlls after compilation) but they don't fit well with the rest of the tools. This means lots of boiler plate repetition we can't kill. Microsoft likes to use code generation for this which I also hate.
- mathgladiator 16y agoC# has some meta-programming with the addition of closures and good polymorphism. Check out how http://kayakhttp.com/ http://kayakhttp.com/ uses them to build a fairly sophisticated async web server.
- Tichy 16y agoI am still not sure how unicode works in Ruby. Therefore I never dare to do any String operations like regular expressions or the the chomp/split he does. The pragmatic book mentions something about kcode (I think), but Rails seems to use something else. Back when I last tried, I couldn't find any definite answers to this. Maybe Ruby 1.9 solves this problem - but is it ready yet? Again, last I tried, there wasn't even a MySQL driver for it.
- draegtun 16y agoTo be fair unicode has never been without issues in Perl & Python either! Perl has generally been the best of the three (IMHO) but Python 3.0 & Ruby 1.9 have probably now caught up.
- sigzero 16y agoraise "Hey dude! Where's My Variable Assignment" if my_variable.nil? I really hate raising an exception like that. I am surprised Rubyists like it like he says they do.
- substack 16y agoI prefer: my_variable or raise 'Hey dude! Where's My Variable Assignment' or else: my_variable.nil? and raise 'Hey dude! Where's My Variable Assignment' since it puts what's being tested in front like with if/then but is also syntactically light-weight.
- robconery 16y agoI could be completely wrong - I do like the "or" syntax as well - reads much better.
- GrandMasterBirt 16y agoWell explained. However many tools of ruby. Tools that we as good developers carry at the bottom of our toolbox for those rare cases where they make life a billion times easier, can also be tools of spaghetti. One of these is the ability to inject behaviors into a class. Its like adding to Array.prototype. The point is that just like a goto statement, it has a few legitimate uses, but most of the time leads to spaghetti code. I think every language has this, and there should be big flashing warnings when tutorials show this methodology stating that "use this only where appropriate, and it is usually only appropriate in these situations:..."