send doesn’t always call private methods anymore (#__send, #__send!, #funcall)
ruby-talk:153672 It is still possible to call them with the newly
introduced #__send! and funcall methods.
Can I make a modest proposal? Can we preserve backward compatibility,
keeping #send as is, and instead pick a new name for the “proper”
public send? I think it would be much better to keep backward
compatibity rather than stress over exact terms ( yes, I’m learning to
make the tough choices There doesn’t seem any good reason to
change how #send works if we are just going to have the same
functionality in another ordinary method, ie. #funcall.
As for a name for the new method, I know #call won’t do b/c of Proc,
unless we want to make an exception for Proc and Proc-like objects –
which seems a viable option. But I’m sure their are other good choices
too.
There doesn’t seem any good reason to
change how #send works if we are just going to have the same
functionality in another ordinary method, ie. #funcall.
Well, there’s the reason of the name of the method. You “send” an
object a message and you shouldn’t be allowed to send private messages.
Can I make a modest proposal? Can we preserve backward compatibility,
Matz has been stating over the past year that 1.9 will break backwards
compatibility with 1.8, and #send is just one of the changes.
String#[] has changed such that requesting a single character returns
a new String (it returns a Fixnum in 1.8). And there are others.
The only way to make sure your code is going to work in 1.9 is to
test, test, test. And when you’re done testing, then do some more
testing.
There doesn’t seem any good reason to
change how #send works if we are just going to have the same
functionality in another ordinary method, ie. #funcall.
Well, there’s the reason of the name of the method. You “send” an object a
message and you shouldn’t be allowed to send private messages.
You’re allowed to send any message; it’s up to the object what to do
with it You could similarly say that you can only call
non-private functions.
In fact, the problem for me is that the names don’t tell you what’s
happening; you just have to know. For that reason, I would like to
see simply send/send! (and __send/__send!). But I think I lost that
argument a long time ago.
In fact, the problem for me is that the names don’t tell you what’s
happening; you just have to know. For that reason, I would like to
see simply send/send! (and __send/__send!). But I think I lost that
argument a long time ago.
FWIW, I also think these would be the most Rubyish names. Please,
Matz, reconsider David’s proposal!
To Tom and others using #send to call private methods: if the method
name is known, then you should immediately change
obj.send(“method”, *args)
to
obj.instance_eval { method(*args) }
IMO, this should be the “official” idiom to call a private method. It
works today and it will work with future versions of Ruby. Use #send
only if the method name has to be determined at runtime.
test, test, test. And when you’re done testing, then do some more
testing.
All you say is correct, but how much we have to change in our code
will of course depend on the amount of change.
After having read this thread I still go for backing up Tom. Please do
not change the behavior of Object#send, IMHO it is not worth it.
If it changes we will of course survive, err maybe, err I hope ;).
Robert
My experience with this is that Matz is doing the right thing. It is
counterintuitive that sending a message to an object should bypass the
guidelines set by the class author. Given that 1.9 is willing to
sacrifice backwards compatibility in order to improve the language, I
don’t really see a problem with fixing this semantic mismatch.
Minor sidebar: One thing I think is a little confusing is the version
numbering. Normally, you wouldn’t expect a minor release version to
break backwards compatibility. I am not familiar with the roadmap, but
as a Ruby user, I find this a bit confusing. I wonder if people will
upgrade too quickly, not realizing what they are getting into.
This is particularly relevant to send, since I think changing send’s
semantics can introduce some very subtle bugs that might not show up
right away. For example, a use of send that invokes a private method
will now invoke method_missing, which in turn might do something that
seems reasonable but is not the intended behavior.
Well, there’s the reason of the name of the method. You “send” an object a
message and you shouldn’t be allowed to send private messages.
You’re allowed to send any message; it’s up to the object what to do
with it You could similarly say that you can only call
non-private functions.
In fact, the problem for me is that the names don’t tell you what’s
happening; you just have to know. For that reason, I would like to
see simply send/send! (and __send/__send!). But I think I lost that
argument a long time ago.
Well, if my modest proposal doesn’t carry, then I throw my hat in with
yours.
Will there be a compatability flag to allow 1.9 to act like 1.8 for
cases in
which backwards compatability was broken? That way you could take
advantage
of new features w/o having to rewrite an existing codebase all at once.
Matz has been stating over the past year that 1.9 will break backwards
compatibility with 1.8, and #send is just one of the changes.
String#[] has changed such that requesting a single character returns
a new String (it returns a Fixnum in 1.8). And there are others.
The only way to make sure your code is going to work in 1.9 is to
test, test, test. And when you’re done testing, then do some more
testing.
crapzor! So there’s no guide (yet) for making 1.9 suitable code?
And does anyone know of a release for 2.0? I’m getting pretty psyched
to countdown the days until.
Thanks,
-------------------------------------------------------|
~ Ari
crap my sig won’t fit
Not quite. This time I’m asking that we do the opposite. Pick a new
name for “public send” and leave the old one alone. (Of course,
possibly someone else suggested it before, but I don’t recall).
In fact, the problem for me is that the names don’t tell you what’s
happening; you just have to know. For that reason, I would like to
see simply send/send! (and __send/__send!). But I think I lost that
argument a long time ago.
FWIW, I also think these would be the most Rubyish names. Please,
Matz, reconsider David’s proposal!
David’s proposal always made sense to me, too. The send/funcall
distinction just doesn’t sing out its meaning to me.
To Tom and others using #send to call private methods: if the method
name is known, then you should immediately change
obj.send(“method”, *args)
to
obj.instance_eval { method(*args) }
That rewrite can be a source of errors if instead of “args” you have
some expression that depends on self:
obj.send(“method”, x, y) # x and y are methods of self
Will there be a compatability flag to allow1.9to act like 1.8 for cases in
which backwards compatability was broken? That way you could take advantage
of new features w/o having to rewrite an existing codebase all at once.
Ron
That way lies the Perl path.
Don’t get me wrong. I came to Ruby from Perl and I enjoyed it just
fine, but I’m much happier with Ruby. There are some things I don’t
entirely agree with, but some of those are changing with 1.9. They’re
changing to be better, which leads to breaking some code that depends
on the old behavior. Backwards compatibility is nice, but it’s not so
important that you hobble progress.