#send in 1.9


#1

Looking over 1.9’s change of #send, ie.

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 :wink: 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.

T.


#2

On Aug 2, 2007, at 10:54 AM, Trans wrote:

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.

James Edward G. II


#3

On 8/2/07, Trans removed_email_address@domain.invalid wrote:

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.

Blessings,
TwP


#4

Hi –

On Fri, 3 Aug 2007, James Edward G. II wrote:

On Aug 2, 2007, at 10:54 AM, Trans wrote:

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 :slight_smile: 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.

David


#5

2007/8/2, removed_email_address@domain.invalid removed_email_address@domain.invalid:

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.

Regards,
Pit


#6

On 8/2/07, Pit C. removed_email_address@domain.invalid wrote:

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

In that case you should change even if the method name is unknown

obj.instance_eval { send( method, *args) }

Thx for the tip however.

Robert


#7

On 8/2/07, Tim P. removed_email_address@domain.invalid wrote:

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


#8

I’ve written up some interesting use cases on this here:
http://dev.zeraweb.com/design-blog-14/

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.

Dan


#9

On Aug 2, 12:32 pm, removed_email_address@domain.invalid wrote:

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 :slight_smile: 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.

I agree. A rose smells just as sweet . . .

I just hate the thought of all the programs that will break for what
seems like a rather minor distinction in semantics.

T.


#10

On Aug 2, 12:32 pm, removed_email_address@domain.invalid wrote:

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 :slight_smile: 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.

T.


#11

On 8/2/07, Trans removed_email_address@domain.invalid wrote:

Well, if my modest proposal doesn’t carry, then I throw my hat in with
yours.
Right, just let me hang in there all by myself, thanx :wink:
R.


#12

On Aug 2, 3:15 pm, “Robert D.” removed_email_address@domain.invalid wrote:

On 8/2/07, Trans removed_email_address@domain.invalid wrote:

Well, if my modest proposal doesn’t carry, then I throw my hat in with
yours.

Right, just let me hang in there all by myself, thanx :wink:
R.

Lol. Well, I really did mean “if”. So it’s only half a hanging.

T.


#13

On 8/2/07, Trans removed_email_address@domain.invalid wrote:

Lol. Well, I really did mean “if”. So it’s only half a hanging.
I know , I thought it was worth a short +1, but we are not bad losers
:))
Robert


#14

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.

Ron


#15

On Aug 2, 2007, at 12:30 PM, Tim P. wrote:

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


#16

On Aug 2, 9:05 pm, Daniel DeLorme removed_email_address@domain.invalid wrote:

(all)
funcall
send!
__send!
instance_send

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

T.


#17

Pit C. wrote:

2007/8/2, removed_email_address@domain.invalid removed_email_address@domain.invalid:

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

can be rewritten as:

args = [x, y]
obj.instance_eval { method(*args) }


#18

2007/8/3, Joel VanderWerf removed_email_address@domain.invalid:

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

can be rewritten as:

args = [x, y]
obj.instance_eval { method(*args) }

Good catch, Joel. It never happened to me, but you’re right: the two
snippets I’ve shown are not equivalent. Thanks for pointing this out.

Regards,
Pit


#19

On Aug 2, 4:10 pm, “ronald braswell” removed_email_address@domain.invalid wrote:

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.


#20

advantage
on the old behavior. Backwards compatibility is nice, but it’s not so
important that you hobble progress.


-yossef

Thanks, Yossef.

Ron