Little Things

T

Trans

i wouldn't say it's less OO. according to wikipedia

in fact, it's quite OO: Pervasives (Introspector or whatever we might call it)
is the object that sees through to the pristine unalterable state of any other
object. it interacts with these other objects by sending messages. this is
quite inline with any OO i've ever heard of, for instance

we might as well say something like

Guru.send student, message, :compassion

http://en.wikipedia.org/wiki/Object_(computer_science) seems to agree
somewhat

"In the programming paradigm, object-oriented programming, an object is an
individual unit of run-time data storage that is used as the basic building
block of programs. These objects act on each other, as opposed to a
traditional view in which a program may be seen as a collection of
functions, or simply as a list of instructions to the computer. Each object
is capable of receiving messages, processing data, and sending messages to
other objects. Each object can be viewed as an independent little machine
or actor with a distinct role or responsibility."

i understand the sentiment. still, what we after is a methodology which
ensures that some aspects of objects can always be reached. it's quite OO to
delegate the responsibility of locating and preserving that aspect to another
object. syntactically one might prefer

reveal{ object }.send msg

but the impl would obviously be the same since, here, we've just popped up to

(Kernel|Object).reveal

remember that much of ruby works this way: puts, fork, exit, raise, etc are
all hung off of Kernel|Object.


yes. and the related object_id, instance_eval, instance_variable_get, etc.
the fact that some, but not all, methods of an object are required for it to
function at a reasonble level, and that those same methods are not protected
or separated from 'normal' methods in any way has frequently been an issue for
the few metaprogramming libs i've written such as traits, attributes, xx, etc.

regards.

you make a strong argument ara. i know we've discussed this particular
question before, i forget what we came up with then. i'll have to
search for it. but at the moment it would be nicer with a shorter
notation. what about some type of alternate "dot" that demands the Guru
module definition:

obj$send message

or something. (Hmm... didn't someone suggest using the dollar sign in a
similar syntax before? What was that about?)

T.
 
J

James Edward Gray II

If Ruby sticks with #2 were actually in luck, there's already a
unspoken precedence for important meta-methods to stay out of the way
of common names, namely those prefixed with object_ (as in object_id)
and instance_ (as in instance_variable_get) One for public sending
(object_send) and one for private sending (instance_send) --at
least in
MHO.

We're not sending an object though, we're sending a message. Perhaps
send_message() would be a less clashed name, but I doubt it.

James Edward Gray II
 
R

Rob Sanheim

Precisely right -- both of you -- it just depends on your viewpoint:

1) There should be a unalterable means of dynamically sending a message
to an object. PERIOD. That seem reasonable, but...

2) one can argue #1 is rather non-OOP like and if someone wants to
monkey with the "send" method then that's their silly business.

So we have a choice, do we deviate from strict OOP, or do accept the
dangers of overridablity and recognize that generalized meta-code which
we except to work in all cases certainly will not.

Presently Ruby has adopted the 2nd approach, and uses the #send method
to do it. Unfortunately this method makes the danger of overridablity
even worse b/c, as David points out, it is also a rather common word.
So what happens? To mitigate the danger we get #__send__. This gives
some reassurance of guaranteed sendability while still being
overridable if absolutely necessary. Right? Unfortunately NO! It just
exacerbates the issue further. Not only is there's really no point to
using #send since all assurance rests in __send__, but the assurance
itself is an illusion b/c __send__ can be overridden. We've gained
nothing by this but additional complexity.

So we have a choice. Either pick option #1 instead. Or stick with #2
and choose a single method name that is relatively uncommon.

If Ruby sticks with #2 were actually in luck, there's already a
unspoken precedence for important meta-methods to stay out of the way
of common names, namely those prefixed with object_ (as in object_id)
and instance_ (as in instance_variable_get) One for public sending
(object_send) and one for private sending (instance_send) --at least in
MHO.

How is this better then having send and the __send alias, along with
the corresponding bang methods? It seems to me having one method that
means "send a message", and then having one version be the "dangerous"
version is much more obvious then having object_send and
instance_send.

If a ruby newbie tried "send" and saw it fail due to a private method,
I bet once they saw "send!" in the docs or in irb they would
immediately know how it works. Its aligns perfectly with many other
things in the std lib, and fits perfectly with POLS.

As for protecting from people overriding it, I think having the
underscore forms is enough. YSYEO ("You'll shoot your eye out.") I'm
sure there are programs were object_id and other meta-methods are
overridden. All you can do is warn people against doing it, test your
code, and of course choose libraries that behave well.


- Rob
 
A

ara.t.howard

I bet once they saw "send!" in the docs or in irb they would
immediately know how it works. Its aligns perfectly with many other
things in the std lib, and fits perfectly with POLS.
agreed.

As for protecting from people overriding it, I think having the
underscore forms is enough. YSYEO ("You'll shoot your eye out.") I'm
sure there are programs were object_id and other meta-methods are
overridden. All you can do is warn people against doing it, test your
code, and of course choose libraries that behave well.

alternatively, it can be externalized so no matter how hard you muck about
with objects you cannot break certain unalienable behvaiours we desire them to
have.

regards.

-a
 
D

Devin Mullins

so long as we have to rely on objects responding to certain methods certain
constructs, such as those that meta-programming cut to, can be made
difficult
since the very methods we require to operate can be over-ridden. this
is why
we have
__id__
__send__
Hrm. I thought the reason __id__ and __send__ where there was because id
and send are fairly common names and useful for custom methods in, say,
ActiveRecord::Base and Socket.
are examples. by moving the essential methods outside of the object
itself an
into a frozen introspector

Introspector.object_id obj
Another option is to make __id, __send, and __send! impervious to
metaprogramming. Say, they are listed in #methods because that's useful
for irb-learning, but remove_method and the like are no-ops when called
on __id, __send, and __send!. That way you can have your BlankSlate and
eat it, too. Thoughts?

Devin
 
T

Trans

Rob said:
How is this better then having send and the __send alias, along with
the corresponding bang methods? It seems to me having one method that
means "send a message", and then having one version be the "dangerous"
version is much more obvious then having object_send and
instance_send.

I just explained that. I'm sorry but I don't understand how is is not
clear. I guess all I can do is try to sum up on a bullet point basis:

1) you have 4 methods when only 2 are needed

2) and two of those methods are ugly shadow methods

3) #send is common enough a word as to be too easily over-ridden

4) using #__send to circumvent this makes #send completely pointless
If a ruby newbie tried "send" and saw it fail due to a private method,
I bet once they saw "send!" in the docs or in irb they would
immediately know how it works. Its aligns perfectly with many other
things in the std lib, and fits perfectly with POLS.

not really since 90+% of the time "!" means in place change. personally
i could care less about the !, to me that's not really the point --
there's a more fundamental issue here. To me POLS is

1) methods starting with 'object_' or 'instance_' are Vital methods and
should not be overridden (unless you know exactly what the heck it is
you're doing)

2) methods starting with 'instance_' provide Internal access to the
receiver.
As for protecting from people overriding it, I think having the
underscore forms is enough. YSYEO ("You'll shoot your eye out.") I'm
sure there are programs were object_id and other meta-methods are
overridden. All you can do is warn people against doing it, test your
code, and of course choose libraries that behave well.

There was a reason #id was changed to #object_id.

T.
 
T

Trans

Devin said:
Hrm. I thought the reason __id__ and __send__ where there was because id
and send are fairly common names and useful for custom methods in, say,
ActiveRecord::Base and Socket.

Another option is to make __id, __send, and __send! impervious to
metaprogramming. Say, they are listed in #methods because that's useful
for irb-learning, but remove_method and the like are no-ops when called
on __id, __send, and __send!.

Again, there would be no point in having #object_id, #send and #send!
in that case. If given a choice between a method that works and one
that might work, which one would you choose?
That way you can have your BlankSlate and
eat it, too. Thoughts?

__id__ ought to be deprecated. we have object_id.

T.
 
M

Martin DeMello

It basically means "I agree", or "Add me to the list of people who
support this."

And is likely from the system of voting via wiki page, where you edit
the page and add one to the number following the option you support

martin
 
D

Devin Mullins

Trans said:
Again, there would be no point in having #object_id, #send and #send!
in that case. Agreed.

If given a choice between a method that works and one
that might work, which one would you choose?
The simple one. Here, __* are all unlikely to be overridden (and well,
can't - Ruby should stop you from overriding them). __ is a flag that
this is a special thing that can't be overridden. It's ridiculously
ugly, as a sign that it should be used sparingly, both by the language
designers and by users. Finally, the names are short, for when you *are*
writing metacode.

My point was that we need not extract the cool methods into Pervasives
in order to achieve metaprogramming simplicity.

(On a side note: How do you find the true class of a BlankSlate?)

Devin
 
D

dblack

Hi --

alternatively, it can be externalized so no matter how hard you muck about
with objects you cannot break certain unalienable behvaiours we desire them
to
have.

Do you really think no one will ever do:

def Pervasives.send
# ...
end

? :)


David

--
Q. What is THE Ruby book for Rails developers?
A. RUBY FOR RAILS by David A. Black (http://www.manning.com/black)
(See what readers are saying! http://www.rubypal.com/r4rrevs.pdf)
Q. Where can I get Ruby/Rails on-site training, consulting, coaching?
A. Ruby Power and Light, LLC (http://www.rubypal.com)
 
D

dblack

Hi --

If a ruby newbie tried "send" and saw it fail due to a private method,
I bet once they saw "send!" in the docs or in irb they would
immediately know how it works. Its aligns perfectly with many other
things in the std lib, and fits perfectly with POLS.

I'll add that if a nuby tries "send", said nuby had better realize
that it is using a fairly powerful technique and would be well advised
to educate itself fully about it.


David

--
Q. What is THE Ruby book for Rails developers?
A. RUBY FOR RAILS by David A. Black (http://www.manning.com/black)
(See what readers are saying! http://www.rubypal.com/r4rrevs.pdf)
Q. Where can I get Ruby/Rails on-site training, consulting, coaching?
A. Ruby Power and Light, LLC (http://www.rubypal.com)
 
T

Trans

Devin said:
My point was that we need not extract the cool methods into Pervasives
in order to achieve metaprogramming simplicity.

Yes, you're right. It's not neccessary. But it's also not
metaprogramming with guaranteed behavior. I tend to lean toward the
guaranteed bahavior myself. But the other is okay IF the methods stay
out or our way --but that doesn't mean they have to be ugly and it
certainly doesn't mean we should think we have solved the problem by
adding an extra ugly alias.
(On a side note: How do you find the true class of a BlankSlate?)

In my version I added an intermediary. Eg.

blankslate.self.class

(though I've never been sure what the best name for it is)

T.
 
T

Trans

Hi --



I'll add that if a nuby tries "send", said nuby had better realize
that it is using a fairly powerful technique and would be well advised
to educate itself fully about it.

True for "instance sending" (eg funcall/send!/etc.), but is #send
really all that? Isn't it just a dynamic dot? If what you say is true
then why not:

obj.call! message

and

obj.fcall! message

And extrapolating over the whole board of Ara's Pervasives:

id!
class!
methods!
...etc...

"!" means powerful!

T.
 
A

ara.t.howard

The simple one. Here, __* are all unlikely to be overridden (and well, can't
- Ruby should stop you from overriding them). __ is a flag that this is a
special thing that can't be overridden. It's ridiculously ugly, as a sign
that it should be used sparingly, both by the language designers and by
users. Finally, the names are short, for when you *are* writing metacode.

My point was that we need not extract the cool methods into Pervasives in
order to achieve metaprogramming simplicity.

(On a side note: How do you find the true class of a BlankSlate?)

Pervasives.class obj

;-)

-a
 
A

ara.t.howard

Hi --



Do you really think no one will ever do:

def Pervasives.send
# ...
end

? :)

yes. the Pervasives module would be designed at the C level to prevent
modification, if you read my initial post you'll see that's it's entire
purpose:

harp:~ > cat a.rb
class Pervasives
freeze
class << self
freeze
end
end

class Pervasives
def self.send
end
end

harp:~ > ruby a.rb
a.rb:9: can't modify frozen object (TypeError)

i know this can be subverted, but it can be done at the C level.

the point is to have a single object responsible for maintaining and retrieving
certain unalterable traits of objects. this can either be done somehow for
every object or for one object. i prefer the one object approach because it
streamlines the api: you don't have to remember send! vs. send or object_eval
vs instance_eval, you use the Pervasives handle with the normal method to cut
straight to the heart of of any object.

regards.

-a
 
D

dblack

Hi --

True for "instance sending" (eg funcall/send!/etc.), but is #send
really all that? Isn't it just a dynamic dot? If what you say is true
then why not:

obj.call! message

and

obj.fcall! message

I'm afraid I don't follow at all.
And extrapolating over the whole board of Ara's Pervasives:

id!
class!
methods!
...etc...

"!" means powerful!

It means "dangerous", and I'm not sure what a dangerous id or class
method would be.


David

--
Q. What is THE Ruby book for Rails developers?
A. RUBY FOR RAILS by David A. Black (http://www.manning.com/black)
(See what readers are saying! http://www.rubypal.com/r4rrevs.pdf)
Q. Where can I get Ruby/Rails on-site training, consulting, coaching?
A. Ruby Power and Light, LLC (http://www.rubypal.com)
 
B

Brian Mitchell

Pervasives.class obj

;-)

-a

Interesting. I found this sort of odd though:

Pervasives.class Pervasives

Not really a bad thing since it is rather contained, but still a little odd.

One idea is to provide a module like Pervasives that is mixed in
rather than external. Object could then make use of those directly and
you could then do this:

class Object
inlude Pervasives # really done in the ruby C code during setup.
undef_meth :__send__
end

Pervasives.instance_method:)__send__).bind(obj).call:)my_message)

Of course a little help from the module might be nice as well:

# Better name?
Pervasives.deliver obj, :__send__, :my_message

Of course, the second one isn't too far off from the original idea but
this does allow both a standard mixin approach and a functional
approach to be used.

Brian.
 
A

ara.t.howard

Yes, you're right. It's not neccessary. But it's also not
metaprogramming with guaranteed behavior. I tend to lean toward the
guaranteed bahavior myself. But the other is okay IF the methods stay
out or our way --but that doesn't mean they have to be ugly and it
certainly doesn't mean we should think we have solved the problem by
adding an extra ugly alias.


In my version I added an intermediary. Eg.

blankslate.self.class

(though I've never been sure what the best name for it is)

i think you guys underestimate the difficulties requiring certain methods
imposes. let's just say you wrote, oh, an xml generator using ruby's cool
method_missing feature. now, you cannot easily have any xml tags that look
like this

xml.ancestors{ 'oops' }
xml.class{ 'oops' }
xml.display{ 'oops' }
xml.extend{ 'oops' }
xml.freeze{ 'oops' }
xml.id{ 'oops' }
xml.method{ 'oops' }
xml.new{ 'oops' }
xml.send{ 'oops' }
xml.taint{ 'oops' }
xml.type{ 'oops' }

not to mention you cannot have tags with dashes or other weird chars in
them.... but that's a separate design flaw with sort of thing.

my point, is that send/send! is only the tip of the iceburg of name clashes
one runs into when doing any serious metaprogramming/dsl work with ruby. it's
one of the bugs people on this list simply ignore but production coders
cannot: "you mean our food products list cannot use the tag 'freeze'!?"

i have to ask anyone who does think this is true to point out their libraries
which make use of either metaprogramming or dsls because i'm positive that any
such libs, including my own, suffer from these kinds un-fixable flaws.

i really think people are not seeing the forest for the trees. the issue with
send/send! is not the name: it's that the concept of both needing certain
methods to work a certain way and allowing, even encouraging via the
popularity of dsl like syntaxes in ruby, that those same methods can be easily
clobbered sets up a loosey-goosey mess that those of us who require our code
to run un-attended for months on end get stomach cramps over.

regards.

-a
 

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,768
Messages
2,569,574
Members
45,049
Latest member
Allen00Reed

Latest Threads

Top