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

D

dblack

Hi --

How can I best rephrase, rewrite, etc the definition to show that
reflection is a key tool for doing manipulation, not something that
does manipulation itself?

I still don't have what I consider a complete fix on what we
collectively mean by metaprogramming, but I think I'd say that Ruby's
R&I facilities are preconditions of, or create a hospitable
environment for, metaprogrammming techniques.

For example:

unless obj.respond_to?(meth) # R&I
obj.singleton_class.class_eval {
define_method(meth) &block # metaprogramming, arguably
}
end

(using my favorite non-existent method, singleton_class :)


David

--
David A. Black
(e-mail address removed)

"Ruby for Rails", from Manning Publications, coming April 2006!
http://www.manning.com/books/black
 
G

Gregory Brown

Hi --



I still don't have what I consider a complete fix on what we
collectively mean by metaprogramming, but I think I'd say that Ruby's
R&I facilities are preconditions of, or create a hospitable
environment for, metaprogrammming techniques.

Agreed. It's what makes us barbers instead of butchers, a nice big mirror :=
)
 
C

Chad Perrin

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.
 
G

Gregory Brown

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 )
 
S

Steve Litt

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

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 :)

SteveT

Steve Litt
http://www.troubleshooters.com
(e-mail address removed)
 
S

Steve Litt

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 Litt
http://www.troubleshooters.com
(e-mail address removed)
 
G

Gregory Brown

If someone can show me an advantage to adding methods and instance variab= les
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 bene= fit
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 :)

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.
 
D

dblack

Hi --

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.

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
(e-mail address removed)

"Ruby for Rails", from Manning Publications, coming April 2006!
http://www.manning.com/books/black
 
G

gwtmp01

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 Wright
 
C

Chad Perrin

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.

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.
 
J

James Britt

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.

Really? I thought they were simply reparsed by method_missing into
messages of the form find( <assorted criteria>) 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
http://www.artima.com/rubycs/ - 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
 
G

gwtmp01

Really? I thought they were simply reparsed by method_missing into
messages of the form find( <assorted criteria>) 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 Wright
 
G

Gregory Brown

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 metaprogrammin=
g.
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 <finish me later> 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?
 
D

dblack

Hi --

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 <finish me later> 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, <finish me later> is, in a sense, what yielding
implies.


David

--
David A. Black
(e-mail address removed)

"Ruby for Rails", from Manning Publications, coming April 2006!
http://www.manning.com/books/black
 
S

Steve Litt

Hi --



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

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
 
S

Steve Litt

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 Wright

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 Litt
http://www.troubleshooters.com
(e-mail address removed)
 
H

Hal Fulton

Steve said:
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.

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
 
H

Hal Fulton

Steve said:
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. :)

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
 
J

James Britt

Gregory said:
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...




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.

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.

http://www.oreillynet.com/ruby/blog/2006/01/moping_up_with_herbal_cialis.html

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
http://www.artima.com/rubycs/ - 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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top