Feature #2013

[PATCH] a = *b calls b.*@

Added by Jeremy Evans over 4 years ago. Updated over 1 year ago.

[ruby-core:25192]
Status:Assigned
Priority:Normal
Assignee:Yukihiro Matsumoto
Category:-
Target version:Next Major

Description

=begin
This makes the * operator operate more similarly to the + and - operators. The binary versions of + and - call methods named + and -, while the unary versions call methods named +@ and -@. The binary * operator calls the method named *, but the unary * operator calls the method toa currently, and used to call toary in 1.8.6 (and at some point may have called to_splat).

I think this makes for more consistent behavior, and hopefully it isn't just a foolish consistency. I brought up this idea as a question in Shugo Maeda's presentation at RubyKaigi 2009, and discussed it with Matz at Lone Star Ruby Conf 2009, and he thought the idea had merit.

Here's a basic example how this would look:

class MultiplePersonality
def *@
[self, [self, self]]
end
end

mp = MultiplePersonality.new
p1, mp2 = *mp

This comes with a patch that appears to work from my simple testing, but this is my first time working with the internal ruby code, so I apologize in advance if it doesn't do things correctly.

The patch modifies parse.y so the above is no longer a syntax error. It adds a USTAR token to the parser to represent that *@ token. It modifies the splatting to call *@ instead of toa. Also, for backwards compatibility, it adds *@ to BasicObject, and has it call toa if it responds to toa. This allows code that defines toa and expects that the unary * operator will call to_a to still work.

This patch is mostly for consistency, but it also allows the programmer to make to_a return one thing, and the unary * operator return something else. I can think of the following use case:

# Represents an abstract set of rows in the database
class Dataset
def toa
retrieve
database_rows
end
def *@
[self]
end
end
dataset = Dataset.new

# Explicitly asking for an array means I want
# an array of database rows represented by the
# dataset.
rows = dataset.to_a

# If the dataset had any rows, I want to debug print
# each row separately. However, if it did not have
# any rows, I want to debug print the dataset itself.
p(*(rows.empty? ? dataset : rows))

I'd like to thank Eleanor McHugh for helping me find the key part of ruby that needed to be modified to support this (in vm_insnhelper.c).
=end

unary_star_op_svn.diff Magnifier (3.99 KB) Jeremy Evans, 08/30/2009 02:53 PM

History

#1 Updated by Marc-Andre Lafortune over 4 years ago

  • Category set to core
  • Assignee set to Yukihiro Matsumoto

=begin

=end

#2 Updated by Yusuke Endoh about 4 years ago

  • Target version set to Next Major

=begin
Hi,

This makes the * operator operate more similarly to the + and - operators.

Interesting. It may be useful to simplify the semantics of multiple
assignment which is considered as one of most complex part of Ruby.

But it is very primitive part of Ruby semantics.
I think that such a spec change must not be included in 1.9.x.

So I set the target of this ticket to 2.0.

--
Yusuke Endoh mame@tsg.ne.jp
=end

#3 Updated by Yuki Sonoda about 4 years ago

=begin
On Sun, Aug 30, 2009 at 2:53 PM, Jeremy Evans redmine@ruby-lang.org wrote:

I think this makes for more consistent behavior, and hopefully it isn't just a foolish consistency.  I brought up this idea as a question in Shugo Maeda's presentation at RubyKaigi 2009, and discussed it with Matz at Lone Star Ruby Conf 2009, and he thought the idea had merit.

+1
Interesting. But it is so large change for the language feature to add
to 1.9.2. I do not include this feature in 1.9.2.
But I also think it can be added to 1.9.x. What do you think, matz?
Do you want add it to ruby 1.9.x?

-- Yuki Sonoda (Yugui)

=end

#4 Updated by Shyouhei Urabe over 3 years ago

  • Status changed from Open to Assigned

=begin

=end

#5 Updated by Yui NARUSE over 2 years ago

  • Project changed from ruby-trunk to CommonRuby
  • Category deleted (core)
  • Target version deleted (Next Major)

#6 Updated by Yui NARUSE over 2 years ago

  • Project changed from CommonRuby to ruby-trunk

#7 Updated by Yusuke Endoh over 1 year ago

  • Description updated (diff)
  • Target version set to Next Major

Also available in: Atom PDF