On Mar 7, 5:56 am, Pit C. [email protected] wrote:
Object.class_of(foo)
object itself. It’s not very OO-like, but it is immune from this problem.
Object.instance_method(:class).bind(obj).call
“stupid!”
----- 8< -------------------------------------------------------
Implement all the methods you consider to be “metaprogramming” with whatever
names you think are appropriate. Stick it up as a module on rubyforge, in
case anyone comes across the same need as you. Job done, and no need to
change the core language
Brian, this looks a lot like the concept of “mirrors” in the language
Self. See for examplehttp://bracha.org/mirrors.pdffor a discussion. I
like this approach.
This suggestion has been around a long time, Ara reintroduced it
recentaly as “Pervasives”. And yes, it is the easiest to implement and
doesn’t require any change to Ruby’s core. However it suffers from a
few issues.
-
In very rare cases you might actually have a good reason to “trick”
a caller. So still being able to override, say #object_class for
instance, while very dangerous, may nonetheless be desirable --and it
may be as simple as an AOP-like monitor which would have no real
effect on functionality.
-
Having two ways to get the same information isn’t as helpful.
People will still use the old way b/c it’s easier and they know it.
You still won’t be able to use common terms like #class or #send in
your modules. (Of course we could get rid of the old methods
altogether, but I got a feeling that won’t go over well).
-
Using external functions has a very detering inertia of being long
winded. Metaprogramming tends to use a lot of these calls in tight
loc. If one has to type Meta.send(obj, meth) intsead of obj.send(meth)
more than a few times, the code qucikly starts to become much less
readable. That may seem silly, but in the end people just won’t use it
b/c of this (assuming they still have the other option).
-
It’s a lot slower. It would need implementation in Ruby core anyway
to fix this issue.
T.
Hi –
There is already a precedent here: Object#id was renamed to Object#object_id
The precedent thing is always tricky, though. One could also say:
this has already happened once, so we’ve filled the quota Also, I
think #object_id was 100% about the difficulties with name conflicts,
which isn’t an issue with #singleton_method_added.
every object) or Enumerable (included in many objects)?
Kernel#kernel_puts
Enumerable#enumerable_collect
… etc?
I think not. But if we choose some other basis for namespaces (e.g. “normal”
versus “metaprogramming”) then again this crucially depends on recognising
which methods fall into which category, arguing this for each method.
And that’s why I’d rather not get “meta” about it. It seems to me
that determining categorization for each method cannot be better
than determining what the method does and naming it based on that. In
particular, getting into an open-ended debate about what is and isn’t
metaprogramming in Ruby is, I think, unpromising and wasteful.
From that point of view, I’d be happy to see #class changed to
#object_class, in the same way that #id was changed to #object_id
I’m personally in favor of #birth_class and #singleton_class, but I
don’t think that has much traction.
(Incidentally, which of these are metaprogramming? What about “extend”,
“taint”, “freeze”, “respond_to?”)
Good question. My view is that it’s all programming.[1] I think of the
term “metaprogramming”, in connection with Ruby at least, as a
description of what the programming does, rather than what a given
method does.
David
[1] See, e.g.,
http://dablog.rubypal.com/2007/1/7/meta-shmeta-learning-ruby-horizontally
Hi –
On 3/7/07, Brian C. [email protected] wrote:
go willy nilly naming these things whatever we want we’ll be in a
However I agree with you - explicit reflections (which take an object as an
argument, rather than being methods on all objects) are probably a better
idea, to avoid the clutter.
I think the argument is moot unless Matz decides to go this way in a later
version of Ruby; otherwise we’ll still have method soup anyway
But we don’t. The method names in Ruby are hand-crafted with great
care, and they show it. Also, when there are soup-like tendencies,
Matz is eager and happy to discuss them.
(I see the smiley but I’m concerned that the drift of this thread
could be seen as: Matz botched the method-naming thing, so we have to
intervene and figure out how to fix it.)
David
Correction…
namespace :meta do
def send(obj, meth, *args)
should be def send(meth, *args)
Object.instance_method(:send).bind(obj).call(meth, *args)
end
def class(obj)
should be def class
Object.instance_method(:class).bind(obj).call
end
But anyway, you get the idea.
T.
Hi –
On 3/7/07, Brian C. [email protected] wrote:
On Wed, Mar 07, 2007 at 10:07:01PM +0900, David A. Black wrote:
I didn’t write what follows so I guess the quoting got hosed
implement
But we don’t. The method names in Ruby are hand-crafted with great
care, and they show it. Also, when there are soup-like tendencies,
Matz is eager and happy to discuss them.
(I see the smiley but I’m concerned that the drift of this thread
could be seen as: Matz botched the method-naming thing, so we have to
intervene and figure out how to fix it.)
No, that wasn’t intended at all.
I know; I was just concerned that, with the references to soup and
things being half-implemented and so on, people could get the
impression that this was all being ascribed to some failing on the
part of Matz. If so, that would be a meta-impression; I definitely
know that you’re not saying that
I’m not arguing that the methods are badly named, although I sympathise with
the argument that #class awkwardly clashes with the ‘class’ keyword.
So do I. self.class is definitely not a high point. And the biggest
problem is probably that it brought about the creation of the #type
method, which to this day, I believe, makes it harder than it should
be for people to get the type != class thing.
class Object < BasicObject
include Kernel
include Reflection
… etc
end
But then, you still wouldn’t get any benefit unless you explicitly created
your new objects under BasicObject rather than Object, so there’s not much
practical benefit.
There must be a way (though I’m multitasking too much right now to
figure it out) to do something like create your own modules that
consist of methods that already exist in other modules. Or something.
That would be kind of interesting.
David
On Wed, Mar 07, 2007 at 10:36:31PM +0900, David A. Black wrote:
practical benefit.
There must be a way (though I’m multitasking too much right now to
figure it out) to do something like create your own modules that
consist of methods that already exist in other modules. Or something.
That would be kind of interesting.
Hmm. Clearly this sort of stuff could go into a module; then anything
which
is interested in reflections could do, say,
def process(a)
a.extend Reflection
a.instance_methods.each { ... }
...
end
Unfortunately, this causes a permanent change in the object being
reflected
upon - an unintended Heisenberg-like side-effect.
However, suppose you could temporarily add a module:
def process(a)
b = a.insert Reflection
b.instance_methods.each { ... }
...
end
That would give an easy API, less cumbersome than
Meta.instance_methods(a),
but not pollute the general method namespace of the object. Even better,
because the Reflection module was just inserted, when there is a name
clash
then the method in Reflection will take precedence (e.g. b.class where a
already had overridden ‘class’)
I think this could be implemented using a proxy object / delegator.
But actually, there’s no need to pass any method calls through. You
could
just have a Reflector object:
def process(a)
b = Reflector.new(a)
b.instance_methods.each { ... }
...
end
B.
David A. Black wrote:
And that’s why I’d rather not get “meta” about it. It seems to me
that determining categorization for each method cannot be better
than determining what the method does and naming it based on that. In
particular, getting into an open-ended debate about what is and isn’t
metaprogramming in Ruby is, I think, unpromising and wasteful.
I’m starting to see your point. If we follow to its extreme the logic of
having a consistent prefix for all metaprogramming methods, we wind up
with a huge number of methods that can be considered to be
metaprogramming. Taking Object.instance_methods and removing aliases and
methods meant to be overridden, I get:
class
extend
freeze
frozen?
instance_eval
instance_of?
instance_variable_get
instance_variable_set
instance_variables
is_a?
method
methods
object_id
private_methods
protected_methods
public_methods
respond_to?
send
singleton_methods
taint
tainted?
untaint
Forcing all those methods to have an object_ or instance_ prefix is
self-evidently nonsense. Therefore being a metaprogramming method
cannot be the basis of using those prefixes.
But while I don’t like the sound of “object_is_a?”, I still like the
sound of “object_class” and “object_method”. And I am starting to
realized that the reason is those methods represent /attributes/ of the
object while “is_a?” or “taint” are /actions/. In the case of
attributes, “object_” is not merely a prefix but an adjective to the
ambiguous noun “id”. Same for “class” of “method”. It makes the methods
sound natural, unlike slapping a prefix in front of an action verb. If I
follow that line of reasoning, object_send and instance_send may be bad
ideas. Unless we accept that some exceptions are inevitable, like
instance_variable_[gs]et.
Don’t we just love semantics?
Daniel
On Wed, Mar 07, 2007 at 10:07:01PM +0900, David A. Black wrote:
implement
But we don’t. The method names in Ruby are hand-crafted with great
care, and they show it. Also, when there are soup-like tendencies,
Matz is eager and happy to discuss them.
(I see the smiley but I’m concerned that the drift of this thread
could be seen as: Matz botched the method-naming thing, so we have to
intervene and figure out how to fix it.)
No, that wasn’t intended at all.
I’m not arguing that the methods are badly named, although I sympathise
with
the argument that #class awkwardly clashes with the ‘class’ keyword.
By “soup” I mean that even an empty object has a zillion methods
inherited
from Object and Kernel. I don’t dispute there are good reasons for each
one;
e.g. if you had to write “$stdout.puts” instead of “puts”, or
“Kernel.require ‘foo’”, those would be off-putting. All I’m saying is
that
objects will always have these zillion methods, unless Matz decides to
modularise it, so adding a few more (like extra reflection methods under
your own naming scheme) wouldn’t make any difference.
Matz could separate this all out:
class Object < BasicObject
include Kernel
include Reflection
… etc
end
But then, you still wouldn’t get any benefit unless you explicitly
created
your new objects under BasicObject rather than Object, so there’s not
much
practical benefit.
Regards,
Brian.
On 3/7/07, Daniel DeLorme [email protected] wrote:
But while I don’t like the sound of “object_is_a?”, I still like the
sound of “object_class” and “object_method”. And I am starting to
realized that the reason is those methods represent /attributes/ of the
object while “is_a?” or “taint” are /actions/.
How is is_a? an action? To me it looks like a predicate which is a
truth-valued function.
To me an action is something which, at least, potentially effects a
state change.
Not that you’re wrong from your point of view, it’s just evidence of
how tricky and personal such categorizations really are.
–
Rick DeNatale
My blog on Ruby
http://talklikeaduck.denhaven2.com/
On Mar 7, 9:47 am, Daniel DeLorme [email protected] wrote:
metaprogramming. Taking Object.instance_methods and removing aliases and
methods meant to be overridden, I get:
method
untaint
Lets back up a second, these are “meta” because they are considered
“critical”, right? The foremost reason for adding a prefix is simply
to make their name more uniq, so as be unlikely to clash with user-
defined method names. Most of these already fit that criteria. Any
that start with instance_ or object_ is uniq enough. And I would think
any of these having a punctuation mark is uniq enough as well. That
leaves:
taint
untaint
Now I’ve always felt the methods, public_methods, private_methods and
protected_methods and singleton_methods were quite wasteful. One
method would suffice for all five, this has been discussed before. And
if we went ahead and did that and called that method #object_methods
and along with it had #object_method. Then all those are good to go
too. Leaving:
class
extend
freeze
send
taint
untaint
Now we all seem to agree that it at least makes sense to say
object_class to go along with object_id. And while I know there’s
resistance to object_send (and instance_send) it makes a heck of a lot
of sense mnemonically. So if we could just go with that then there are
only four methods left:
extend
freeze
taint
untaint
I now sure about extend, but as for the last three. if these are
really critical then I’d take Daniel’s idea about “action” to heart
and add a ! to them. They pretty much embody the idea of “danger”
methods.
freeze!
taint!
untaint!
There may be few methods forgotten here, and they can be considered,
but we’re not after perfection --for that these methods would probably
have to be moved out of Object. But we at least gain a system much
improved.
T.
On Mar 7, 4:44 pm, [email protected] wrote:
freeze
taint
untaint
This reminds me of the routine where George Carlin reduces the ten
commandments to one
Lol!
I now sure about extend, but as for the last three. if these are
really critical then I’d take Daniel’s idea about “action” to heart
and add a ! to them. They pretty much embody the idea of “danger”
methods.
freeze!
taint!
untaint!
Action != danger
But what danger doesn’t invlove action?
Also, ! methods always come in pairs. That’s
not enforced by the language, of course, but it’s the convention: the
! indicates the dangerous version of a pair of methods where there’s
also a non-dangerous version. Those three methods state clearly what
they do in their names, and they don’t occur in pairs, so it’s not a !
situation.
I think that’s just a general occurance. Not a rule. In anycase
there’s a good reason for a different type of “danger” --don’t
override me!
T.
Hi –
On Thu, 8 Mar 2007, Trans wrote:
Now we all seem to agree that it at least makes sense to say
object_class to go along with object_id. And while I know there’s
resistance to object_send (and instance_send) it makes a heck of a lot
of sense mnemonically. So if we could just go with that then there are
only four methods left:
extend
freeze
taint
untaint
This reminds me of the routine where George Carlin reduces the ten
commandments to one
I now sure about extend, but as for the last three. if these are
really critical then I’d take Daniel’s idea about “action” to heart
and add a ! to them. They pretty much embody the idea of “danger”
methods.
freeze!
taint!
untaint!
Action != danger Also, ! methods always come in pairs. That’s
not enforced by the language, of course, but it’s the convention: the
! indicates the dangerous version of a pair of methods where there’s
also a non-dangerous version. Those three methods state clearly what
they do in their names, and they don’t occur in pairs, so it’s not a !
situation.
David
On Thu, Mar 08, 2007 at 07:17:48AM +0900, Trans wrote:
freeze!
taint!
untaint!
Action != danger
But what danger doesn’t invlove action?
Maybe all danger involves action, but not all action involves danger.
Hi –
On Thu, 8 Mar 2007, Trans wrote:
Also, ! methods always come in pairs. That’s
not enforced by the language, of course, but it’s the convention: the
! indicates the dangerous version of a pair of methods where there’s
also a non-dangerous version. Those three methods state clearly what
they do in their names, and they don’t occur in pairs, so it’s not a !
situation.
I think that’s just a general occurance. Not a rule. In anycase
there’s a good reason for a different type of “danger” --don’t
override me!
Well… we’d have an awful lot of !'s if it started meaning that
I’ve never heard Matz discuss the ! in a way that made it sound like
he would use it outside of method pairs, and I’m still not sure what
the purpose would be. It’s not a language-level rule, but I think
it’s the intent behind the !.
David
Rick DeNatale wrote:
But while I don’t like the sound of “object_is_a?”, I still like the
sound of “object_class” and “object_method”. And I am starting to
realized that the reason is those methods represent /attributes/ of the
object while “is_a?” or “taint” are /actions/.
How is is_a? an action? To me it looks like a predicate which is a
truth-valued function.
You are entirely right of course. I was thinking of “verb”, really, and
incorrectly converted that to “action” when in fact not all verbs are
actions.
foo.method == foo’s method (noun). what kind of method?
-> foo.object_method
-> foo.instance_method
-> foo.birth_control_method
foo.send(message) == foo sends (verb) a message. what kind of message?
-> foo.send_object(message)
-> foo.send_instance(message)
-> foo.send_email(message)
But even Matz chose instance_variable_get over get_instance_variable…
Daniel
On Mar 7, 9:02 am, Brian C. [email protected] wrote:
end
I think that could be a damn good idea!
Is there room for two exceptions?
class Object
def object
@_object_reflector ||= Reflector.new(self)
end
def instance
@_instance_reflector ||= InstanceReflector.new(self)
end
end
foo.object.id
foo.instance.send(:P)
(ducks)
T.
Trans wrote:
Now I’ve always felt the methods, public_methods, private_methods and
protected_methods and singleton_methods were quite wasteful. One
method would suffice for all five, this has been discussed before. And
if we went ahead and did that and called that method #object_methods
I kinda like that a little bit. We could have
foo.object_methods.all/to_a
foo.object_methods.private
foo.object_methods.protected
foo.object_methods.public
foo.object_methods.singleton
But I’m not too concerned with “clutter”. A basic Object could have a
bazillion methods as far as I care, as long as they don’t conflict with
methods names that people can reasonably/possibly create on their own.
“private_methods” already has the adjective “private” to qualify the
ambiguous noun “methods”, so changing that adjective to “object” is not
much of an improvement. Adding an adjective to “methods” would be good
but that is already done; methods is just an alias of public_methods.
Daniel
On 3/6/07, Daniel DeLorme [email protected] wrote:
Rick DeNatale wrote:
I must have missed that list of 5-6 problems, a quick re-read of the
thread doesn’t provide an obvious list, but maybe I’m just not reading
it right.
- avoids ugliness like send
send was supposed to be ugly, because it’s a signal that you’re
doing something different.
- reduces chances of naming conflict (CgiRequest#method, Email#send)
Naming conflicts are okay, as long as there are non-conflicting names
(e.g., send or whatever 1.9 is now calling it).
- allows simple pattern match to recognize present and future
meta-programming methods (used for forwarding of non-meta methods)
Erm. Pattern matching is somewhat useful, but I’m not sure that this
is something that would be automatic in any case.
-austin