Ideas on "Why Living Dangerous can be A Good Thing" in Ruby?

On Mon, Jan 09, 2006 at 06:52:20AM +0900, James Edward G. II wrote:

On Jan 8, 2006, at 3:42 PM, Steve L. wrote:

And that’s why I enjoy programming in languages like Ruby, Python
and Java, that protect me from myself.

Wow, that’s a might unusual alliance of languages. I wonder how most
Java programmers would feel about being lumped in with Python and
Ruby on safety…

Surprised, at least.


Chad P. [ CCD CopyWrite | http://ccd.apotheon.org ]

This sig for rent: a Signify v1.14 production from

On Sunday 08 January 2006 05:04 pm, Gregory B. wrote:

On 1/8/06, Steve L. [email protected] wrote:

That’s why I’m glad my electric stove has
lights saying which burners are still hot. And that’s why I enjoy
programming in languages like Ruby, Python and Java, that protect me from
myself.

Java: Yes. (in the average scenario)
Python: Pretty much kinda maybe.
Ruby: You’ll shoot your eye out! :wink:

Everyone says that, but I don’t see it (til it hits me in the eye? :-).

Maybe I’m just used to C, where the slightest mistake leads to a subtle
bug
that happens every couple weeks.

Sure, if I went out of my way I could make Ruby do corruptable things,
whereas
with C I cannot avoid it.

Ruby has beautiful encapsulation. Yeah it could be defeated, but you’d
really
have to try. I want my language to protect me from my own mistakes, not
from
my own death wish.

Personally, I’d NEVER gratuitously add a method or instance var to a
class at
runtime. If I needed more methods than the class provided, I’d subclass
it. I
mean, how hard is it to subclass something, especially in Ruby. Adding
methods and instance variables to classes in real time reminds me of
senators
who add a social security amendment to a defense bill – it’s just bad
business that can lead to no good.

If someone can show me an advantage to adding methods and instance
variables
in real time, and that advantage can’t be realized with normal OOP
techniques, I’ll keep an open mind. But unless it offers me a unique
benefit
that I need, I wouldn’t do it.

It’s easy to use Ruby in a manner that respects encapsulation and a
known
state, and if used that way, I’ll leave my goggles at home :slight_smile:

SteveT

Steve L.

[email protected]

On 1/8/06, Steve L. [email protected] wrote:

Compare them to C :-). Or Perl.

I’m really not sure at all on this but could well written C or Perl be
safer than Ruby?
I’m thinking the answer to that is ‘yes’, but I’m not sure at all why
(and what expense it would come at )

On Sunday 08 January 2006 05:42 pm, Gregory B. wrote:

On 1/8/06, Steve L. [email protected] wrote:

Compare them to C :-). Or Perl.

I’m really not sure at all on this but could well written C or Perl be
safer than Ruby?
I’m thinking the answer to that is ‘yes’, but I’m not sure at all why
(and what expense it would come at )

C is like using a punch press without safety interfaces. A very careful
person
could use it safely, but an inattentive person would lose his thumb.

Ruby is like a punch press with a safety interface. You’d need to try
very
hard to lose your thumb.

Now it just might be that a very careful and attentive C punch press
operator
could operate more safely than a drunk and depressed Ruby punch press
operator, but that’s not a fair comparison IMHO.

SteveT

Steve L.

[email protected]

Hi –

On Mon, 9 Jan 2006, Steve L. wrote:

my own death wish.

Personally, I’d NEVER gratuitously add a method or instance var to a class at
runtime. If I needed more methods than the class provided, I’d subclass it. I
mean, how hard is it to subclass something, especially in Ruby. Adding
methods and instance variables to classes in real time reminds me of senators
who add a social security amendment to a defense bill – it’s just bad
business that can lead to no good.

I’m not sure what you mean by adding an instance variable to a class,
but as for methods, they’re all defined at runtime.

class C
def m
end
end

That code gets executed, and then there’s a class called C with an
instance method m.

I’m not sure what it is that you consider subclassing to be a better
choice than. Are you talking about define_method? Or the practice of
reopening core classes?

David


David A. Black
[email protected]

“Ruby for Rails”, from Manning Publications, coming April 2006!

On 1/8/06, Steve L. [email protected] wrote:

If someone can show me an advantage to adding methods and instance variables
in real time, and that advantage can’t be realized with normal OOP
techniques, I’ll keep an open mind. But unless it offers me a unique benefit
that I need, I wouldn’t do it.

Well, that’s kind of what this whole thread is about. There are a lot
of really great ruby applications that take advantage of this kind of
dynamicity, and we’re trying to come up with a decent explanation of
exactly that… why it’s advantageous. But…

It’s easy to use Ruby in a manner that respects encapsulation and a known
state, and if used that way, I’ll leave my goggles at home :slight_smile:

This is a good point. The language doesn’t force you to go
willy-nilly. It just grants you that freedom, which can be VERY nice,
if you know what you’re doing.

On Mon, Jan 09, 2006 at 07:52:05AM +0900, Steve L. wrote:

could use it safely, but an inattentive person would lose his thumb.

Ruby is like a punch press with a safety interface. You’d need to try very
hard to lose your thumb.

Now it just might be that a very careful and attentive C punch press operator
could operate more safely than a drunk and depressed Ruby punch press
operator, but that’s not a fair comparison IMHO.

Interesting analogy. Let’s expand on that a bit:

C is a punch press with no particular safety features, and in fact it
has just barely enough integrated structure to do its job. You can
create guides and the like, but you have to manhandle them into place
yourself.

Java is a punch press operator that has a bunch of guides, protective
flanges to prevent your fingers getting too close to the business end,
and so on. It has little levers to move stuff in and out of place
easily for different jobs. The downside is that it allows certain job
types, and for anything else you have to start redesigning and modifying
the machine. Of course, you could always reach a hand in there and hit
the button if you really want to lose a thumb, but you might have to tie
a string around the dead-man switch.

Ruby lets you define what “safety” means, and configures itself
accordingly. It has sane defaults. It’s also a programmable punch
press, so it can pretty much do the work on its own without your
interference. If you program it well, you don’t have to be anywhere
near the thing, and thus don’t have to worry about your thumbs. If you
program it poorly, it might suddenly start shuddering across the floor
in its hungry quest for your thumbs.


Chad P. [ CCD CopyWrite | http://ccd.apotheon.org ]

“Real ugliness is not harsh-looking syntax, but having to
build programs out of the wrong concepts.” - Paul Graham

[email protected] wrote:

better
problems that involve dynamically creating methods in classes or on
Those methods don’t exist until you call them at which point they are
defined
and added to the class.

Really? I thought they were simply reparsed by method_missing into
messages of the form find( ) asinvoked, not turned in
“permanent” methods. Interesting.

Which raises a question: Is it metaprogramming if I use method_missing
to parse messages, see if it can reformulate the message into a known,
workable form, and then redispatch by invoking ‘send’? No code writing,
no method adding.

Is that not simply the point of method_missing; i.e., it is simply a
Ruby/OO idiom. Messages need not map to methods.

And then isn’t adding them as methods just an optimization technique to
avoid the cost of calling method_missing on repeated invocations? It’s
memoization for behavior.

Is memoization metaprogramming, or is it only metaprogramming when
behavior is altered?

James

http://www.ruby-doc.org - Ruby Help & Documentation
Ruby Code & Style - Ruby Code & Style: Writers wanted
http://www.rubystuff.com - The Ruby Store for Ruby Stuff
http://www.jamesbritt.com - Playing with Better Toys
http://www.30secondrule.com - Building Better Tools

On Jan 8, 2006, at 5:47 PM, Steve L. wrote:

Personally, I’d NEVER gratuitously add a method or instance var to
a class at
runtime. If I needed more methods than the class provided, I’d
subclass it.

I’m not sure I follow this. You think that subclassing at runtime is
better
in some way than simply adding a method to a class? It is hard to
talk about
this stuff in the abstract. For example, I feel differently about
dynamically
adding methods to Array than I would to a class I created to solve a
particular
problem.

I think it does take a certain amount of paradigm shifting to see
solutions to
problems that involve dynamically creating methods in classes or on
particular
objects. Until you make that shift those facilities seem quite
abstract.

For example, in Rails you can call methods like:

Model.find_by_date
Model.find_by_name
Model.find_by_city
Model.find_by_city_and_date

Those methods don’t exist until you call them at which point they are
defined
and added to the class. It doesn’t make sense to add all the possible
combinations as methods to start with, when you can just create them
on demand.
Only a small subset of all the possible variations will ever by used
by a
particular application anyway. Using subclasses in this case doesn’t
help. How
would you decide which methods to put in the subclass? You would have
to lock in some choices and that would prevent you from, for example,
having
a fully dynamic query interface to your application.

Gary W.

On Jan 8, 2006, at 7:15 PM, James B. wrote:

Really? I thought they were simply reparsed by method_missing into
messages of the form find( ) asinvoked, not
turned in “permanent” methods. Interesting.

I’m not a rail’s guru, but that was my recollection when I looked
into this a couple months ago. It seems like an obvious optimization.

Gary W.

On 1/8/06, James B. [email protected] wrote:

Is memoization metaprogramming, or is it only metaprogramming when
behavior is altered?

I’m a lot more liberal (and maybe naive) in my definition of
metaprogramming.
I think that creating dynamic behavior at runtime is indeed
metaprogramming, even if it hasn’t altered the underlying behavior of
the class itself.

Whenever I sere something to the effect of in the
code, I’m thinking that I’m writing a method that is using some sort
of meta programming.

If i’m not accessing methods or fields I defined before the program
began, and I’m getting some sort of behavior that the program
assembled at runtime, I consider that meta programming, regardless of
changes or lack thereof to underlying state / behavior.

What do others think about this?

On Sunday 08 January 2006 06:14 pm, [email protected] wrote:

Java: Yes. (in the average scenario)

I’m not sure what it is that you consider subclassing to be a better
choice than. Are you talking about define_method? Or the practice of
reopening core classes?

David

Hi David,

I don’t know for sure, because when I read about this stuff my first
reaction
was “I’m not gonna do that!”

I got the impression I could do this:

myclass = MyClass.new
myclass.never_seen_before_attribute = 5

As I said, I didn’t research it because I considered its use to be a
negative,
but stored it in the back of my mind in case I had to maintain code like
that.

SteveT

On Sunday 08 January 2006 06:21 pm, [email protected] wrote:

this stuff in the abstract. For example, I feel differently about
abstract.
and added to the class. It doesn’t make sense to add all the possible

Gary W.

Hi Gary,

I’m trying to understand this. If Model.find_by_city was never defined,
how
can it know what to do? I think I’m missing some big chunk of Ruby
knowledge
here.

Are you saying that when Model.find_by_city is executed, the model looks
at
the database, discovers there’s a city column, and on the fly constructs
a
method to search the table by city?

SteveT

Steve L.

[email protected]

Steve L. wrote:

but stored it in the back of my mind in case I had to maintain code like
that.

No, that is a little more dangerous.

Only a class that specifically supported that kind of behavior
would allow such a thing. See the ‘ostruct’ (OpenStruct)
library. Its author created it mostly as a toy, I think, but
it has been used in many situations. (I would not personally
suggest that all objects should behave that way.)

By the way, it’s very instructive to look at the code for ostruct.

Hal

Hi –

On Mon, 9 Jan 2006, Gregory B. wrote:

Whenever I sere something to the effect of in the
code, I’m thinking that I’m writing a method that is using some sort
of meta programming.

If i’m not accessing methods or fields I defined before the program
began, and I’m getting some sort of behavior that the program
assembled at runtime, I consider that meta programming, regardless of
changes or lack thereof to underlying state / behavior.

What do others think about this?

Interestingly, is, in a sense, what yielding
implies.

David


David A. Black
[email protected]

“Ruby for Rails”, from Manning Publications, coming April 2006!

Steve L. wrote:

I’m trying to understand this. If Model.find_by_city was never defined, how
can it know what to do? I think I’m missing some big chunk of Ruby knowledge
here.

Are you saying that when Model.find_by_city is executed, the model looks at
the database, discovers there’s a city column, and on the fly constructs a
method to search the table by city?

What you’re missing is method_missing. :slight_smile:

When a method doesn’t exist, method_missing gets called. There’s a
default
one that raises an exception, but you can override it with any behavior
you want.

The name of the called method is passed in, e.g., “find_by_city”; so if
you
parse it and see that it has the form “find_by_X” then you can know that
X
is (supposed to be) a field name. Then you just handle it.

A variation on this is to define the method so that next time,
method_missing
will not be called on that name.

Makes sense?

Hal

Gregory B. wrote:

of really great ruby applications that take advantage of this kind of
if you know what you’re doing.
I think my message-oriented programming post on O’Reilly demonstrates
the sort of thing metprogramming and reflection/introspection affords a
developer, or at least the sort thing it leads some of us to do.

Without Ruby’s degree of developer freedom, it becomes
hard-to-impossible to rearrange the language to best express your
intentions.

The B&D languages may make claims to a certain amount of security, but
code that is hard for humans to read and understand is code that is
harder to maintain without introducing subtle bugs. The code may
compile and run without errors, but it may not be doing quite what it is
supposed to.

James

P.S. Looks like rubyurl.com is having issues, if Robby is lurking.

http://www.ruby-doc.org - Ruby Help & Documentation
Ruby Code & Style - Ruby Code & Style: Writers wanted
http://www.rubystuff.com - The Ruby Store for Ruby Stuff
http://www.jamesbritt.com - Playing with Better Toys
http://www.30secondrule.com - Building Better Tools

On Jan 8, 2006, at 10:30 PM, Steve L. wrote:

Are you saying that when Model.find_by_city is executed, the model
looks at
the database, discovers there’s a city column, and on the fly
constructs a
method to search the table by city?

I think Hal already answered this, but yes. If your class defines
the instance method ‘method_missing’ then Ruby will call it when it
can’t
find a method definition. It would look something like this (not
tested):

class Model

def method_missing(method_name, args)
if method_name.to_s =~ /^find_by_(.
)/
# respond to find_by call
else
super # results in standard method not found exception
end
end

end

(Note that the first argument to method_missing is an instance of
Symbol, not
String so you need to call to_s on it in order to compare it to the
regular expression. What is the difference between a Symbol and String
you ask? Um, read the archives.)

This feature of Ruby’s method dispatch protocol allows a class to
implement methods on demand. It can even install a definition for
the missed method so that the next time it will be called directly
instead of being intercepted by method_missing.

Very handy.

Gary W.

On 1/8/06, [email protected] [email protected] wrote:

Interestingly, is, in a sense, what yielding
implies.

But is that yet another piece of the puzzle? Is the fact that ruby
can pass around blocks of codes as just another object part of what
makes it suitable for metaprogramming?

When does plain old dynamicity cross the line to become
‘metaprogramming’?
That’s the million dollar question we’ve yet to answer :slight_smile:

On 1/8/06, Hal F. [email protected] wrote:

Only a class that specifically supported that kind of behavior
would allow such a thing. See the ‘ostruct’ (OpenStruct)
library. Its author created it mostly as a toy, I think, but
it has been used in many situations. (I would not personally
suggest that all objects should behave that way.)

Not all objects, but if your goal is to hold a ton of ‘never before
seen’ attributes, it certainly does help.

I had this exact issue with Ruport, and created a sort of abstract
node for a tree structure, using OStruct. See it here:

Probably a bad idea for most things, but it cut me about a 100 lines
in Ruport :slight_smile: