[vox] Ruby gives you sharp knives (fwd)

Bill Kendrick nbs at sonic.net
Wed Apr 7 16:13:06 PDT 2010


A discussion about languages over on the libSDL mailing list led to this
fellow posting a little bit about Ruby, which I know pretty much nothing
about.  I found it interesting, so figured I'd share here.  Enjoy!

-bill!

----- Forwarded message from Bill Kelly -----

Date: Wed, 07 Apr 2010 16:02:14 -0700
From: Bill Kelly
Subject: Re: [SDL] Off-Topic: Quake II Ported to HTML5
To: SDL Development List <sdl at lists.libsdl.org>

Mason Wheeler wrote:
> Congratulations, you just discovered dynamic typing's dirty little secret.
> It looks really cool in a demo, but it turns out real code hardly uses it at all.
> Data has a type and tends to stay that type far more often than not, so
> why not formalize that and gain the benefits of compile-time type checking
> and static analysis tools?

One thing several individuals who enjoy programming in ruby have
observed about the language is that it "stays out of your way".

Reflecting on a couple decades of programming in C and about
half that for C++ , I still find it hard to pin down or quantify
precisely why i feel more productive in dynamic languages.

But I'd say that when a language really embraces its dynamicity,
the gestalt is more than just the narrow focus on type
declarations.

I wish I had an SDL example to offer, so this could be more on-
topic.

But here's a database example, making use of an Object Relational
Mapping library called Og.

Almost ironically we are going to see some type declarations here,
as the database columns themselves will be typed:

class Address
  property :name, String
  property :company, String
  property :dept, String
  property :addr1, String
  property :addr2, String
  property :city, String
  property :state, String
  property :zip, String
  property :country, String
  belongs_to :order, Order
end

The above does an awful lot; I'll try to be brief.

At compile time, we're defining an ordinary ruby class called
Address ; however, also at compile time the "property" and
"belongs_to" methods are being executed and doing some work.

Neither the "property" nor "belongs_to" methods are part
of Ruby; they've been added by the Og library.

In ruby, there's not a lot of distinction between compile-
time and run-time ; the full interpreter is available at all
times, and one can define or modify classes or methods at
any time.

This level of dynamicity may sound alarming, but I enjoyed
ruby's designer, matz, likening it to trusting the programmer
to use dangerous tools:

 | "open class" is so strong (often too strong), we can break things
 | easily. In other word, Ruby trust you to give you sharp knives, where
 | Python don't. From the Python point of view, it's wrong, I guess.

Anyway.  At "compile-time" the statements in the Address class
above end up both defining methods in the class, as well as
linking the class into the Og library's checklist of which
classes it will be managing as database tables.

When the Og library is then started up at "run-time", like,
for example:

  Og.start(
    :destroy => false,
    :evolve_schema => true,
    :store => :postgresql,
    :name => 'database-name',
    :user => 'db-user'
  )

It will examine its checklist of classes like Address above,
which it knows about simply because such classes were encountered
at compile-time and invoked Og's defining methods like
"property", and it will examine their structure and generate
the SQL / DDL necessary to realize the corresponding schema
in the database.

That's already pretty dynamic, but we're not done yet...

Og has also imbued any class it manages with some additional
on-the-fly run-time dynamicity.

For example, we can say:

  records = Address.find_all_by_city_and_state("Los Angeles", "CA")

  records.each do |rec|
    puts "#{rec.name} #{rec.company}"
  end

Now, with Address.find_all_by_city_and_state, we're calling
a "class method" on Address which didn't even exist until now.

But, like Smalltalk (messageNotUnderstood), Ruby provides a
hook to handle messages sent to a class for which no existing
method can be found to respond to the message.  (method_missing)

So, Og imbues its managed classes with a method_missing
implementation which looks at the method called, and if it
matches a pattern like /find_(all_)?by_(\w+)(_(and|or)(\w+))*/
will implement a method on the fly which performs the
requested search on the appropriate columns.

(And if the Og implementors chose, they could define said
method on the class, such that next time it was called, it
would execute directly as a method rather than virtually via
the method_missing hook.)


Powerful stuff.  Could give more examples, but I hope this helps
illustrate that really dynamic languages offer a lot more power
than just a narrow focus on type declarations.  (And we use it.)


Regards,

Bill

----- End forwarded message -----

-- 
-bill!
Sent from my computer


More information about the vox mailing list