Daily Archives: August 14, 2007

Ruby – First (almost) disappointment

When you are learning a new language, when something is different often the first reaction is that it is bad – after all we fear change.
As I was learning about Ruby objects, I was learning that all members variables are private and that the only way to get at the variables was through setters and getters. I got used to setters and getters when I went from C++ to Java – it has always bugged me that I had to add 10 lines of code and 8 lines of comments just to access a dang member variable the “cool Java” way.
With one of the tenents of Ruby is to dispense with unnecessary cruft – “convention versus configuration” I was surprised when all the books immediately introduce setters and getters right away. I would have thought that there would be a simple way to do this – code like this bothered me:
class Thermo
def set_temp(x) # a setter
@temp=x
end
def get_temp # a getter
@temp
end
end
And they described this in books as if this was a *good thing*. To me it was crap and too much “me-tooing” Java patterns – it was the absolute antithesis of “convention not configuration” – it was overblown syntax – something I hoped to get away from in Ruby – but here in Chapter 3 – was creeping cruft – when would it end? And with this crufty syntax needed for *every* member variable – as far as I was concerned – Ruby was already a failure at delivering on “convention not overblown wasteful, repetitive, and redundant syntax”. Grr. I was only a few weeks into the new language.
So I started reading my five Ruby books and looking in the indexs and searching for things like “ruby sucks” and “ruby setters and getters suck” in Google and trying to learn if there were others as peeved about this as me. I found some peeved folks – and even some folks peeved about this issue. But somewhere along the line I got a clue.
Actually I had a clue all along – ActiveRecord does *not* use the setter/getter pattern faux-Java style – and since ActiveRecord is written in Ruby – it must be doing something much niftier than faux-Java setters and getters. You just refer to
thermo.id
Not
thermo.get_id thermo.set_id(1234)
To get the Id of an active record object – I liked that – how do they do that? So the hunt was on.
By the way there needs to be a newbie list where people like me can ask dumb questions like this and get a boot to the head to quickly learn this stuff. Like dummies@ruby.org or some such.
So I was sure there was a better idea – there was hope. I will bypass all the pages that I waded through until I found this one.
http://www.ruby-doc.org/docs/UsersGuide/rg/accessors.html
It shows two patterns of setters that make a LOT of sense – far more sense than the drivel above. I will switch to his code here:
class Fruit
def kind=(k)
@kind = k
end
def kind
@kind
end
end
f2 = Fruit.new
f2.kind = “apple”
f2.kind
Now that is a sweet syntax – particularly when accessing and setting the member variable. Kind of like C++ again – operator overloading – a nice clean syntax that allows me to do things “in context” – working with the compiler as my pal rather than pounding it with syntax as in Java (sorry – still a little bitter about the loss of operator overloading when I left C++ five years ago).
Of course – Ruby does this one better below.
This *is* “convention over configuration” – or at least “don’t repeat yourself”. “Don’t repeat yourself” is a very important concept in programming as it keeps us from making transcription mistakes. So the super-sweet Ruby-regains-absolute-advantage syntax is as follows:
class Fruit
attr_accessor :kind
end
f2 = Fruit.new
f2.kind = “apple”
f2.kind
Ah – I am back happy with Ruby again – no wasted moves – all graceful – like a ballet dancer – I can express what I want in a concise syntax that clearly communicates my intent to the future reader of the code. And if I want to add a little “special stuff” to my setter – simply drop back to the attr_reader and do my own setter as in the previous example.
Whew! I was kind of grouchy with Ruby for a few hours – but I am feeling better now – and in addition the Ruby approach is am improvement beyond C++ and Java IMHO – simple syntax for simple situations with the option to go deeper using more syntax only when there is a real need.
Also I got a little back on the operator overloading front… Cha-Ching.
Let me know if there is a mailing list to help me get through these mental blocks more easily.