Twelve rules of Ruby

Scott Adams of Dilbert fame talked about learning twelve concepts of
something and in the progress become more knowledgeable about given
subject than most of the other people.

Original blogpost here: http://www.dilbert.com/blog/entry/rule_of_twelve
And followup with actual example:
http://www.dilbert.com/blog/entry/twelve_rules_of_energy_efficient_building/

Question I am proposing is found in subject line, what would be The
Twelve Rules for Ruby.

I am not that great programmer and one of the reasons for starting this
thread is to give some direction to my learning. And then to write more
code to actually learn.

I am not expecting for everyone to post 12 things, but maybe few that
they think should be included on this kind of list.

Thanks!

I’d say one of the main suspects here is closures:
returning from a block is different from returning from a lambda is
different from returning from a Proc, …:
def f block
block.call
‘f’
end

f(Proc.new { return ‘Proc.new’ }) #=> LocalJumpError
f(proc { return ‘proc’ }) #=> ‘f’ in 1.8, LocalJumpError in 1.9
f(lambda { return ‘lambda’ }) # => ‘f’

def g
f(Proc.new { return ‘Proc.new’ })
‘g’
end

g() #=> ‘Proc.new’

etc. etc. See also this very nice summary here:
http://innig.net/software/ruby/closures-in-ruby.rb
If you know that, you should be able to impress a bunch of people g

Greetz!

Hi –

On Tue, 14 Jul 2009, Panu Kinnari wrote:

I am not that great programmer and one of the reasons for starting this
thread is to give some direction to my learning. And then to write more
code to actually learn.

I am not expecting for everyone to post 12 things, but maybe few that
they think should be included on this kind of list.

Here’s half a dozen. I would say that if everyone understood these
principles, and really stopped to think about them when puzzled by
something that Ruby was doing, or something that wasn’t working in
their code, it would make a huge difference overall to people’s
experiences learning and using Ruby:

  1. Classes are objects.
  2. Objects don’t “have” methods; they have the intelligence to resolve
    messages by looking for methods along their class/module lookup
    path.
  3. Every instance variable you ever see in any Ruby program belongs to
    whatever object “self” is at that moment, without exception. (Which
    is one reason that understanding how “self” gets assigned is
    absolutely vital.)
  4. A code block is a syntactic construct, not an object.
  5. Class variables are not class variables, in the sense of belonging
    to a particular class. They are class hierarchy variables.
  6. Inheritance (A < B) is not the same as, and not related to, nesting
    (A::B).

The first one on the list, alone, is worth the price of admission :slight_smile:

David

Not sure why they wrapped weirdly (at least on my screen), but here’s
a correctly-wrapped version, I hope.

  1. Classes are objects.
  2. Objects don’t “have” methods; they have the intelligence to resolve
    messages by looking for methods along their class/module lookup
    path.
  3. Every instance variable you ever see in any Ruby program belongs to
    whatever object “self” is at that moment, without exception. (Which
    is one reason that understanding how “self” gets assigned is
    absolutely vital.)
  4. A code block is a syntactic construct, not an object.
  5. Class variables are not class variables, in the sense of belonging
    to a particular class. They are class hierarchy variables.
  6. Inheritance (A < B) is not the same as, and not related to, nesting
    (A::B).

I would think that the twelve rules should be in the form of what things
are, not what they are not.

It is also implied that the twelve rules would be something to learn
early on … so it’s for those just starting to learn ruby.

The rules should then be reasonably clear.

To say that x is not a character does not tell me as much as telling me
that x is an integer.

Saying that the identity of self may change and that its best to learn
the rules of when it changes, does not tell me as much as finding away
to tell me the rules.

David A. Black wrote:

http://www.dilbert.com/blog/entry/twelve_rules_of_energy_efficient_building/
they think should be included on this kind of list.
path.
The first one on the list, alone, is worth the price of admission :slight_smile:

David

Very interesting David. Thanks for these!

t.

Tom C., MS MA, LMHC - Private practice Psychotherapist
Bellingham, Washington, U.S.A: (360) 920-1226
<< [email protected] >> (email)
<< TomCloyd.com >> (website)
<< sleightmind.wordpress.com >> (mental health weblog)

Objects don’t “have” methods

Hey David, you gotta tell this Dave T. so that he can talk about
this in new pickaxes too. I sort of stopped learning after reading
pickaxe, because this concept still surprises me … :>

Hi –

On Tue, 14 Jul 2009, Garry F. wrote:

Saying that the identity of self may change and that its best to
learn the rules of when it changes, does not tell me as much as
finding away to tell me the rules.

http://www.manning.com/black2 :slight_smile:

I suppose I’m very teaching-oriented, in the sense that I’m mainly
interested in “rules” for understanding and using Ruby successfully. I
don’t think there’s that much point making a list of how self works[1]
in the absence of explaining why (at least in part) it’s important to
understand it.

Of course, there are no twelve rules. Better is for everyone to
interpret the invitation how they see fit. We don’t have to (and
won’t, and can’t) reach some kind of twelve-rule consensus. That’s a
red herring.

David

[1] In a method definition, it’s the object that received the message.
In a or module class definition body, outside of a method definition,
it’s the class or module object. At the top level, it’s a special
“backstop” object called “main”. In an instance_eval or instance_exec
block, it’s the receive of the instance_eval message. In a
class_/module_eval block, it’s the class or module object. That’s off
the top of my head (too lazy to look at the book sitting next to me
:slight_smile: but I think that’s about it.

On 14 Jul 2009, at 15:33, Garry F. wrote:

I would think that the twelve rules should be in the form of what
things are, not what they are not.

It is also implied that the twelve rules would be something to learn
early on … so it’s for those just starting to learn ruby.

I think the point is that most people involved with Ruby - even those
with considerable experience - would be unlikely to consciously know
all twelve (or however many) of these rules. In that sense they’re the
theoretical basis of expertise as opposed to competence.

Of course actual expertise cannot be distilled into an arbitrarily
small set of rules because it embodies much more than just theoretical
knowledge: you have to pay your dues if you want an instinctual and
wide-ranging grasp of any subject, mostly by making large numbers of
errors and then reflecting on their significance.

A couple of things I’d put on my personal list of Ruby rules:

  1. Ruby is duck-typed. The type of an object is not the same as its
    class and objects can (in a complex program at least some will) change
    their identity at runtime. The only definitive type information
    therefore comes from message passing.
  2. Learn Ruby/DL or (j)ruby-ffi and leverage your platform for all
    it’s worth.
  3. Metaprogramming is a right, not a privilege.

Ellie

Eleanor McHugh
Games With Brains
http://slides.games-with-brains.net

raise ArgumentError unless @reality.responds_to? :reason


From: David A. Black [email protected]
To: ruby-talk ML [email protected]
Sent: Tuesday, July 14, 2009 7:43:56 AM
Subject: Re: Twelve rules of Ruby

Hi –

The Well-Grounded Rubyist :slight_smile:

I suppose I’m very teaching-oriented, in the sense that I’m mainly
interested in “rules” for understanding and using Ruby successfully. I
don’t think there’s that much point making a list of how self works[1]
in the absence of explaining why (at least in part) it’s important to
understand it.

Of course, there are no twelve rules. Better is for everyone to
interpret the invitation how they see fit. We don’t have to (and
won’t, and can’t) reach some kind of twelve-rule consensus. That’s a
red herring.

David

[1] In a method definition, it’s the object that received the message.
In a or module class definition body, outside of a method definition,
it’s the class or module object. At the top level, it’s a special
“backstop” object called “main”. In an instance_eval or instance_exec
block, it’s the receive of the instance_eval message. In a
class_/module_eval block, it’s the class or module object. That’s off
the top of my head (too lazy to look at the book sitting next to me
:slight_smile: but I think that’s about it.


David A. Black / Ruby Power and Light, LLC
Ruby/Rails consulting & training: http://www.rubypal.com
Now available: The Well-Grounded Rubyist (The Well-Grounded Rubyist)
Training! Intro to Ruby, with Black & Kastner, September 14-17
(More info: http://rubyurl.com/vmzN)

– END of David’s Reply.

Yep, I suspected myself that trying to state the rules might make a tome
of a rule … but those rules there are also worth the price of
admission, Now i know what self is.

Just for curiosity I looked up the etiology of red herring and got this
http://ask.yahoo.com/20010718.html

I looked at the book online with interest. One of the frustrations for
me is that I have some older books on Ruby I bought a few years ago …
I got one that tells the student to try to implement something, and
mentions that it is easy to do it wrong, but the author never explains
what he thinks is the “Right” way of doing things. Now that I am laid
off and urgently adding Ruby to my set of programmer skills, things in
these books simply do not work any more and I am left to guess around
trying to get things working.

Example: I am following an example from the book Ruby from novice to
Professional … and I am directed to use scaffolds to create my working
project, but the procedure does not create a working program any more
(The scaffold does NOT pick up the fields in the record, so trying to
create a new record, just shows the header, the save button and the back
button.

Neither me, nor my friend who has for years been making a living
programming Rails and Ruby from his living room knows if this is a bug
or an intentional change, or if there is some new syntax to make
scaffold create a complete scaffold instead of a ladder with no rungs.

The reason I bring this frustration out, is I am interested in finding a
book that doesn’t leave me in the lurch of having to make guesses with
no guidance, and where the examples work with the current version of
ruby in wide use today. Surprises are like being in a dark cave and
having your flashlight go out without warning.

My rails is 2.3.2 and Ruby version 1.8.6

Hi –

On Wed, 15 Jul 2009, Marc H. wrote:

Objects don’t “have” methods

Hey David, you gotta tell this Dave T. so that he can talk about
this in new pickaxes too. I sort of stopped learning after reading
pickaxe, because this concept still surprises me … :>

That’s what keeps it interesting, isn’t it? :slight_smile:

I certainly use the “have” terminology informally. But it’s important
to understand that “obj has a ‘talk’ method” is really shorthand for:
“obj can successfully resolve the message ‘talk’ because there is a
‘talk’ method definition in one of the classes or modules in its
method lookup path.” The wordier version will enable you, for example,
to understand super, inheritance, include, extend, the difference
between undef_method and remove_method, and various other things…
whereas “has”, while a handy shorthand, doesn’t pan out as a real
description of the object model.

David

On Tue, Jul 14, 2009 at 11:46 AM, David A. Black[email protected]
wrote:

That’s what keeps it interesting, isn’t it? :slight_smile:

I certainly use the “have” terminology informally. But it’s important
to understand that “obj has a ‘talk’ method” is really shorthand for:
“obj can successfully resolve the message ‘talk’ because there is a
‘talk’ method definition in one of the classes or modules in its
method lookup path.” The wordier version will enable you, for example,
to understand super, inheritance, include, extend, the difference
between undef_method and remove_method, and various other things…
whereas “has”, while a handy shorthand, doesn’t pan out as a real
description of the object model.

I know what you are driving at, but there are some things about your
statement of that rule which bother me.

First of all, as you just stated, object DO in a sense have methods,
in the same sense I have, say, an iPhone, because I know how to find
it, usually.

And the idea that “they have the intelligence to resolve messages by
looking for methods along their class/module lookup path” is a bit of
a pedagogical lie. If an object has any intelligence that
intelligence is held in its methods, and state. Objects don’t really
know how to find their methods, it’s the implementation of the
language whether you call that an interpreter, or a virtual machine,
which knows how to do that.

How best to think about such things depends on where you are on the
journey of learning. A certain perspective can get a learner over a
hump, even it it’s not exactly correct. But it can also lead to the
stuff you and I were tweeting about a few days ago, when I discovered
that there are adults in this world who firmly believe that Two
Thousand and One, means 2000.1 because their fourth or fifth grade
minds were taught that “and means decimal point,” and never realized
that this was a shortcut way of telling them that when they see a . in
a digit string, it means decimal point and they should say “and” and
then the following decimal fraction.

At one level, the important thing is to be able to reason about how
methods are found based on the reference implementation of chained
classes and model proxies in MRI. On the other hand, this approach is
actually talking about a shadow of the implementation displayed on the
walls of Plato’s cave. There are certainly conceivable Ruby
implementations which used a more Self, or JavaScript like object
model, in which methods were more closely associated with instances,
but still acted AS IF they had the MRI implementation for all outside
observers.

In my years dealing with language standards, I’ve learned the power of
that explicit ‘AS IF’ to separate intent from implementation.


Rick DeNatale

Blog: http://talklikeaduck.denhaven2.com/
Twitter: http://twitter.com/RickDeNatale
WWR: http://www.workingwithrails.com/person/9021-rick-denatale
LinkedIn: http://www.linkedin.com/in/rickdenatale

Marc H. wrote:

Objects don’t “have” methods

Hey David, you gotta tell this Dave T. so that he can talk about
this in new pickaxes too. I sort of stopped learning after reading
pickaxe, because this concept still surprises me … :>

Related to this, objects do not have “attributes” or “properties”; they
have private instance variables that may be access by sending messages.
Typically those messages have the same name as the private instance
variable, but that’s a convention, not a requirement.

Some Ruby literature encourages developers to think of objects in a more
Java-ish sense, as having public and private properties (i.e.
“attributes”), and the core idea of accessing private instance data via
message sending gets obscured. This makes later understanding of
metaprogramming harder than it need be.


James B.

www.jamesbritt.com - Playing with Better Toys
www.ruby-doc.org - Ruby Help & Documentation
www.rubystuff.com - The Ruby Store for Ruby Stuff
www.neurogami.com - Smart application development

On 14 Jul 2009, at 16:24, Garry F. wrote:

The reason I bring this frustration out, is I am interested in
finding a book that doesn’t leave me in the lurch of having to make
guesses with no guidance, and where the examples work with the
current version of ruby in wide use today. Surprises are like being
in a dark cave and having your flashlight go out without warning.

My rails is 2.3.2 and Ruby version 1.8.6

I can’t comment on the Rails side of things as that’s not my primary
interest, but for Ruby 1.8.6 the second edition of the PickAxe and
David’s excellent Ruby for Rails should get you up to speed on the
language. I also recommend the second edition of The Ruby Way by Hal
Fulton which is full of interesting snippets (and there’s also The
Rails Way of which I’ve heard good reports).

Ellie

Eleanor McHugh
Games With Brains
http://slides.games-with-brains.net

raise ArgumentError unless @reality.responds_to? :reason

Eleanor McHugh wrote:

interest, but for Ruby 1.8.6 the second edition of the PickAxe and
David’s excellent Ruby for Rails should get you up to speed on the
language. I also recommend the second edition of The Ruby Way by Hal
Fulton which is full of interesting snippets (and there’s also The Rails
Way of which I’ve heard good reports).

Grab Greg Brown’s Ruby Best Practices, too.


James B.

www.jamesbritt.com - Playing with Better Toys
www.ruby-doc.org - Ruby Help & Documentation
www.rubystuff.com - The Ruby Store for Ruby Stuff
www.neurogami.com - Smart application development

Hi –

On Wed, 15 Jul 2009, Joel VanderWerf wrote:

a password.
I’m not sure what the point of these analogies is, I’m afraid. I don’t
think that the notion of “X has Y” is, or has to be, absolutely
uniform across all usage and all values of X and Y. It’s possible for
humans to have bank accounts, and yet for the verb “to have” to be
problematic in relation to Ruby objects and their methods. In fact, I
believe that’s how things stand.

(It’s also possible to get into the fine grain of what it means to
“have” a bank account or a phone – and I think in both cases it would
transpire that “having” comes in many flavors [I can physically destroy a phone, even if you “have” it; you cannot produce a bank account on request and put it on the table, even though you “have” it; etc.] – but that’s not really that interesting, I think.)

As you say, the location of such intelligence is a question that can
wait until someone starts poking around in the interpreter.

Yes and no. I’m all for poking into interpreters (if you don’t believe
me, see http://ruby-versions.net :slight_smile: but I absolutely don’t believe
that one has to hitch descriptions of Ruby’s object model to
descriptions of specific interpreters.

For a beginner, it’s more important to have a model of how method lookup
works (model in the sense of science, not rails). If the easiest way of
stating this model is in terms of what methods an object has (and what class
they were acquired from), so be it.

It’s the easiest at the very beginning, but it quite quickly (say,
early in the afternoon on the first day of training :slight_smile: becomes more
of a hindrance than a help. Then, once someone understands what else
is going on – that is, once someone graduates to a more featureful
model, one that encompasses more of Ruby’s observable behavior –
“has” reverts to being helpful, because it’s the most sensible
informal way of stating the relation between an object and a method.
(Or “concise”, if you don’t like “informal”.)

Let me put the whole thing this way: encouraging people to let go, at
least provisionally, of the notion that objects “have” methods and,
instead, inquire into what goes on from the object’s perspective in
the process of resolving a message into a method, is very, very high
on the list of things that I have seen, over the years, have an
immediate, tremendous, permanent positive effect on people’s
understanding of Ruby and their ability to use Ruby productively. And
it’s absolutely upward compatible with being someone who is capable of
taking on board (in due course) the fact that different interpreters
work differently under the hood. There’s no conflict there at all.

David

Rick DeNatale wrote:

On Tue, Jul 14, 2009 at 11:46 AM, David A. Black[email protected] wrote:

Objects don’t “have” methods
First of all, as you just stated, object DO in a sense have methods,
in the same sense I have, say, an iPhone, because I know how to find
it, usually.

Yep. You said it better than I was about to (not just this line, but the
whole post). I was going to say "people don’t ‘have’ bank accounts; they
have the intelligence to perform transactions by visiting a web site and
entering a password.

As you say, the location of such intelligence is a question that can
wait until someone starts poking around in the interpreter.

For a beginner, it’s more important to have a model of how method
lookup works (model in the sense of science, not rails). If the easiest
way of stating this model is in terms of what methods an object has (and
what class they were acquired from), so be it.

The original example was about how to approach keeping your house cool,
not a manual on the innards of air conditioning. It said, for example,
don’t bother about the walls because the roof is more important.

On that basis my first rule would be:

  1. Don’t worry about any Ruby feature that you don’t need to use. It’s
    very, very powerful but unless you need to write something like Rails or
    you are an astrophysics PhD, then ignore all the fancy stuff.

David A. Black wrote:

Hi –

On Wed, 15 Jul 2009, Joel VanderWerf wrote:

As you [Rick] say, the location of such intelligence is a question that can
wait until someone starts poking around in the interpreter.

Yes and no. I’m all for poking into interpreters (if you don’t believe
me, see http://ruby-versions.net :slight_smile: but I absolutely don’t believe
that one has to hitch descriptions of Ruby’s object model to
descriptions of specific interpreters.

Exactly. There might be a compatible ruby interpreter in which each
object really does “have”, in every possible sense of the word, all of
the methods that obj.send(:methods) lists. The difference between this
and MRI with its own lookup algorithm is unlikely to matter to a
beginner, as long as s/he has a consistent way of talking about the
methods that an object responds to, and how they got that way.

“has” reverts to being helpful, because it’s the most sensible
informal way of stating the relation between an object and a method.
(Or “concise”, if you don’t like “informal”.)

I’d explain these concepts in terms of the basic tools that I, even
after years of rubying, still use to explore the capabilities of an
object:

irb(main):001:0> s = “foo”
irb(main):003:0> s.methods.grep /slice/
irb(main):005:0> s.class.ancestors
irb(main):006:0> String.instance_methods(false)
irb(main):007:0> s.method :dup # to find out where the method came from
=> #<Method: String(Kernel)#dup>

I still think of objects as having methods, because Object#methods tells
me what methods an object has.

That’s not incompatible with talking about how an object came to have
those methods, and all the different ways that can happen.

On Jul 14, 2009, at 06:16 , David A. Black wrote:

Not sure why they wrapped weirdly (at least on my screen), but here’s
a correctly-wrapped version, I hope.

Rick did a very good job with some of the philosophical wanking but I
thought I’d expand a bit on David’s list… I have to be a pedant now
and then :slight_smile:

(please note, I’m still pre-caffeine… I’m sure I missed something in
the editing phase)

  1. Classes are objects.

I prefer to tell my students: EVERYTHING is an object, even classes.

I think it conveys the ontology a bit better.

  1. Objects don’t “have” methods; they have the intelligence to resolve
    messages by looking for methods along their class/module lookup
    path.

See #1. Classes, modules, and their anonymous kin have methods.

  1. Every instance variable you ever see in any Ruby program belongs to
    whatever object “self” is at that moment, without exception. (Which
    is one reason that understanding how “self” gets assigned is
    absolutely vital.)
  2. A code block is a syntactic construct, not an object.

See #1. EVERYTHING is an object, even blocks.

  1. Class variables are not class variables, in the sense of belonging
    to a particular class. They are class hierarchy variables.

I know what you’re getting at, but it might be worth having the
contrast of class instance variables in there so others understand too.