Is Ruby pass-by-reference or pass-by-value?

I was confused by Ruby’s variable assignment paradigm for a while, and even after reading this Stackoverflow thread and checking out out other threads about the same thing I was no closer to understanding it clearly. And in the words of the great Albert Einstein …

“if you can’t explain it simply you don’t understand it well enough”

I eventually figured it out by reading page 53-54 of what I think is the best Ruby book on the market right now, turns out its actually pretty simple to understand.

Ruby ALWAYS passes references to objects on assignment, BUT some types in ruby are stored in variables as immediate values because they are immutable.

For example (you can try these out in irb)

me = we = “we”
me #=> “we”
we #=> “we”
me.upcase!
me #=> “WE”
we #=> “WE”

me = we = [1, 2, 3]
we #=> [1, 2, 3]
me #=> [1, 2, 3]
we << 4
we #=> [1, 2, 3, 4]
me #=> [1, 2, 3, 4]

Ruby does this for all its types, but with primitives that are immutable, namely integers, symbols, nil, and the booleans true and false, it takes a shortcut and actually stores the value IN the variable itself, because … what are you going to do? change an immutable object? :)

Pretty clever when you think about it IMO.

I upgraded to Ruby 2.1.0 and all I got was this lousy T-shirt …

Ruby 2.1.0 was released about 2 weeks ago, and after seeing a notable speed performance improvement with my Rails app when going from 1.9.3 to 2.0.0 I was excited to see if the same would happen with Ruby 2.1.0.

I quickly ran another set of very casual tests, mainly running test suites and noting startup times of rails commands and rake tasks at the command line. What I saw was a 20% improvement in those tasks. Nothing to sneeze at …

Excited, I rushed to upgrade my tiny Rails app to ruby 2.1.0 and after doing it I tracked the difference in New Relic

This was my result (deployment happened about 18:00 on December 25th, app is setup to run with one puma worker and 8-16 threads proxied to nginx)

New Relic graph after upgrading to Ruby 2.1.0 (18:00 on the graph)As you can see, there wasn’t much of an improvement in performance at all. In fact here is the graph after a full day of running in the wild.

New Relic graph of my app after a full day of running with Ruby 2.1.0

 

So while you might get better startup times on Rails tasks, you probably won’t see too much of a speed boost on your servers.

Improved GC

What I found interesting, though, is the improved garbage collection. The brown part of the graph (GC execution) almost completely disappears in ruby 2.1.0. And its no wonder, a lot of work went into improving Garbage collection in ruby 2.1.0

The garbage collector in Ruby 2.1 implements a form of generational garbage collection, with Ruby calling their implementation RGenGC (Restricted Generational Garbage Collection).  This replaces the “Mark & Sweep” implementation used in previous versions of Ruby

Using RGenGC provides high compatibility with existing extensions while still bringing performance improvements.  Popular objects Array, String, Hash, Object, and Numeric are Write-Barrier protected, thus able to take advantage of the RGenGC system

The moral of the story? Ruby 2.1.0 has a small performance boost over Ruby 2.0 and upgrading to it should give you a bit of a boost with your Rails app, more if its a pretty big app with non-trivial time spent doing GC.

PS: Brian Hempel has created an awesome site that benchmarks ruby versions using Rails. His results are in line with what I found
PS2: Sorry there wasn’t actually a T-shirt, I just liked the title

tracking down *exactly* where a Ruby object method is defined

Ever spent way longer than you would have liked trying to find out exactly where a particular Ruby object method is defined, especially in something like Rails where a method could have been included from a plugin, gem, helper, or otherwise metaprogrammed in?

Well with Ruby 1.9.3 … you can now do this

Post.first.method(:published?).source_location

and get this back

=> ["/Users/xxx/.rvm/gems/ruby-1.9.3-p362/gems/state_machine-1.1.2/lib/state_machine/machine.rb", 752]

Blew my mind, and I’ve been writing Ruby for almost 6 years now.

Ruby 2.0.0 is looking like its going to be substantially faster than Ruby 1.9.3

In very unscientific tests Ruby 2.0 is 60-70% faster than 1.9.3.
Very promising.

PS: I couldn’t get my test suite to run in Ruby 2.0.0 but I managed to run the very simple
“time bundle exec rake environment” test

The average was
- 7.74s for ruby 2.0.0
- 11.8s for ruby 1.9.3-p368, a 65% speed improvment, right in line with the results from the gist
- 17.07s for rubinius 2.0.0 (1.9 variant) … yeah thats slow

Unit Testing and Mock Objects

Recently, I’ve been working hard to plug one of the biggest holes in my game … testing. I stumbled across this article, which helped make a lot of things clear for me, with respect to mocking and its relation to Unit testing.

This is partially due to the fact that most geeks don’t actually know what a unit test is. They think that testing the methods of a specific class constitutes a unit test, but that’s only part of the story. A unit test test is when you test the methods of a specific class in isolation, and the difference is critical. You know how some people call us “computer scientists”. Yeah, well this is the science part.

If you’re not doing this, you are not unit testing. That’s not meant to deride what you’re doing. I mean that as a literal statement of fact. Anyone, for example, who is using the built in Rails “unit” testing framework with fixtures (or FactoryGirl fixtures) is guilty of this. No test that relies on a separate class, or API, or interfaces with a database in any way is a unit test. It is an integration test (some people call them functional test), and when something goes wrong it is just a matter of time before it misleads you.

Enjoy the article – The Thing about Mock Objects

How to get Ruby Native gems to install on your windows machine

The bane of any ruby/rails developer on a windows box (apart from piddling performance) is seeing the dreaded …
‘gem install error – ‘cl’ is not recognized as an internal or external command’

No more!
Devkit, a tool used by the folks who create the Windows Ruby Installer of each version of ruby helps you with (most) gems that need to be built natively.
Muchos Gracias to them for graciously providing it to us.

From the books: Exceptions to Ruby’s standard variable assignment by reference behavior

The un-reference: immediate values
Some objects in Ruby are stored in variables as immediate values. These include integers, symbols (which look like :this), and the special objects true, false and nil. When you assign one of these values to a variable (x = 1), the variable holds the value itself, rather than a reference to it

– From page 54 of The Well Grounded Rubyist by Robert Black

Filed under Things I did not know about Ruby :D

41A+B9T4yGL._SS500_

php’s print_r equivalent in ruby on rails

I was going through my google analytics logs today and I noticed that a lot of folks were coming to my site on Google searches for stuff like ‘print_r + ruby on rails‘.

So I figured I’d write a blog post about it, because I’ve had the same problem.

What you’re looking for is ‘inspect’.

If you have an array, hash or object that you want to take a quick-and-dirty look at just type in

objectname.inspect

eg:

posts.inspect

or if you’re in rails just do …

render :text => posts.inspect and return false

and you’ll get an output of the contents of said array, hash or object.

Here is a screen capture of a quick irb session to show you how it works.

print_r equivalent in ruby on rails

I hope this helps.

Gotcha in Ruby for PHP Developers with multiple assignments of array to variables

The more I work with Ruby and Ruby on Rails, the more I begin to understand (though not necessarily agree with) a lot of the vitriol that has been aimed at PHP over the years by developers using other more rigorous languages.

A few weeks back I ran into this little speed bump while working with Ruby on Rails, where I was  trying to do a multiple assignment like this

x = y = z = []

Most seasoned Rubyists will be waving their arms around and yelling “NOOOOOO!!!”
But coming from a PHP background this seemed perfectly okay to me.

Continue reading

fixing webrick error – WARN TCPServer Error: Bad file descriptor – bind(2) – on windows

I was working on a Ruby on Rails project with Netbeans today when I went to fire up webbrick to test something in the app.

I immediately got an error like this

=> Booting WEBrick...
=> Rails application started on http://0.0.0.0:3000
[2008-03-18 16:36:59] INFO  WEBrick 1.3.1
=> Ctrl-C to shutdown server; call with --help for options
[2008-03-18 16:36:59] INFO  ruby 1.8.6 (2007-03-13) [i386-mswin32]
[2008-03-18 16:36:59] WARN  TCPServer Error: Bad file descriptor - bind(2)
C:/ruby/lib/ruby/1.8/webrick/utils.rb:73:in `initialize': Bad file descriptor - bind(2) (Errno::EBADF)
        from C:/ruby/lib/ruby/1.8/webrick/utils.rb:73:in `new'
        from C:/ruby/lib/ruby/1.8/webrick/utils.rb:73:in `create_listeners'
        from C:/ruby/lib/ruby/1.8/webrick/utils.rb:70:in `each'
        from C:/ruby/lib/ruby/1.8/webrick/utils.rb:70:in `create_listeners'
        from C:/ruby/lib/ruby/1.8/webrick/server.rb:75:in `listen'
        from C:/ruby/lib/ruby/1.8/webrick/server.rb:63:in `initialize'
        from C:/ruby/lib/ruby/1.8/webrick/httpserver.rb:24:in `initialize'
        from C:/ruby/lib/ruby/gems/1.8/gems/rails-1.2.3/lib/webrick_server.rb:58:in `new'
         ... 7 levels...
        from C:/ruby/lib/ruby/gems/1.8/gems/rails-1.2.3/lib/commands/server.rb:39
        from C:/ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in `gem_original_require'
        from C:/ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in `require'
        from script/server:3

Continue reading

Apparently the creator of Ruby on Rails doesn’t comment his code … kinda

Here’s some excerpts from DHH’s post and comments yesterday on 37 signals

  • The short answer is that we don’t document our projects. At least not in the traditional sense of writing a tome that exists outside of the code base that somebody new to a project would go read …
  • Further more, I don’t really find it necessary for the kind of work that we do. Our biggest product, Basecamp, is about 10,000 lines of code. That really isn’t a whole lot in the grand scheme of things. Everything we do is build is also using Ruby on Rails, which means that most Rails programmers would know their way around our applications straight away. It’s the same conventions and patterns used throughout.
  •  Finally, we write our application in a wonderfully expressive and succinct programming language like Ruby that leads itself very well to a programming style like the one Kent Beck preaches in Smalltalk Best Practice Patterns. Keep your methods short and expressive. On average, our models have methods just four lines long. Adding documentation to a method should usually only be done when you’re doing something non-obvious that can’t be rewritten in an obvious way.
  • [comment] Wim, yes there’s RDoc. I just generally don’t use it for projects. When methods are only an average of 4 lines long written in a language like Ruby, it’s often faster and better to merely browse the code base rather than rely on explicit commenting.

Keep in mind that I’m no Ruby on Rails genius, and from the little I’ve done I can see where DHH is going with this. But I’ve always thought that this argument of a language being so succinct and clear that you don’t have to write comments is just a bit silly for a couple of reasons.

  • I believe that you don’t write code for machines, you write code for people (other developers). So any help you can give them in navigating your code is typically good to have. It saves them time and their employers money … that is what being a great consultant is about, you have to be thinking in terms of how to help your clients’ business and saving them money falls in that category.
  • People who use this line of argument are either too lazy to comment and are trying to justify it …
  • … or don’t understand that there are developers of all skill levels in the industry. So whereas, someone with your skill level would be able to navigate your code quickly, someone who wasn’t as good might take longer …why not avoid that.

Note, that I’m not of the school of thought of commenting just for the sake of it, like I’ve heard some “blub programmers” do. However, I do think that you should always be thinking of other developers when you code and if commenting can get them to a point where they can modify your code in 1 minute instead of a minute and a half … then you should comment.

In the end, I guess its a bit unfair to criticize DHH, because its not clear that he doesn’t comment his code much … though its easy to infer that. I just know from my experience that people who say things like he says have a tendency to have 3 lines of comments in some piece of code 500 lines long.

But if you’re a “rockstar developer, I guess everyone has to dance to your tune, wherever you are right?

Ruby reddit and top ten list of Ruby gems!

Quick note to say that  I just discovered the brand new Ruby Reddit which is really fortuitous now that I’m spending a lot of time with Ruby on Rails. From there I found the “Ten Essential Ruby Gems” … which I am installing and screwing with as I type :]

Many thanks  to Reginald Braithwaite who runs the immensely popular software development blog Raganwald for his post about the Ruby Reddit.

random dude on the “internets” disembowels Ruby on Rails …

I spent the whole weekend reading about Rails setup and deployment, discovering Ngnix + mongrels as a new Rails hosting setup option and started getting in depth with Rails with Obie Hernandez’s “The Rails Way“.

I don’t know much about the guts of PHP or Rails (that is something I am working very hard to remedy) but I was fascinated by this google group post  “Rails is shitty” … Continue reading