Feature #2013
closed[PATCH] a = *b calls b.*@
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 to_a currently, and used to call to_ary 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 to_a. Also, for backwards compatibility, it adds *@ to BasicObject, and has it call to_a if it responds to to_a. This allows code that defines to_a 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 to_a
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
Files
Updated by marcandre (Marc-Andre Lafortune) almost 15 years ago
- Category set to core
- Assignee set to matz (Yukihiro Matsumoto)
=begin
=end
Updated by mame (Yusuke Endoh) over 14 years ago
- Target version set to 3.0
=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
Updated by yugui (Yuki Sonoda) over 14 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
Updated by shyouhei (Shyouhei Urabe) almost 14 years ago
- Status changed from Open to Assigned
=begin
=end
Updated by naruse (Yui NARUSE) almost 13 years ago
- Project changed from Ruby master to 14
- Category deleted (
core) - Target version deleted (
3.0)
Updated by naruse (Yui NARUSE) almost 13 years ago
- Project changed from 14 to Ruby master
Updated by mame (Yusuke Endoh) over 11 years ago
- Description updated (diff)
- Target version set to 3.0
Updated by mame (Yusuke Endoh) almost 7 years ago
- Status changed from Assigned to Rejected
I'm closing this ticket since the discussion has been stalled completely.
I still think this is an interesting proposal. If you (or anyone else) are interested in this feature, please create a new ticket. It would be good to reimplement it for trunk, and to investigate its merit on real-world applications and the compatibility problem.