Feature #474

Hash#<<

Added by Anonymous almost 7 years ago. Updated about 4 years ago.

[ruby-core:18370]
Status:Rejected
Priority:Normal
Assignee:Yukihiro Matsumoto

Description

=begin
This was discussed a some months ago on Ruby-talk. I don't know if that discussion led to any consideration on Core, so I wanted to post it up as a feature request.

To recap, the idea is:

h = Hash.new
h << [:a, 1]
h << [:b, 2]
h #=> {:a=>1, :b=>2}

This creates a polymorphism between associative arrays and hashes, which ultimately could be useful to mixins. And now that Hash supports insertion order too, it makes further sense. There was a particular usecase exemplified in the fore-mentioned thread. But since I can't find it I can't show it here. I just recall thinking it was compelling. Perhaps other's can recall?
=end

History

#1 Updated by Brian Candler almost 7 years ago

=begin

module Enumerable

def map(&block)
  o = self.class.new
  each do |e|
    o << yield(e)
  end
  o
end

end

But that breaks a lot of useful stuff. e.g.

a = File.open("/etc/passwd") { |f| f.map { |line| line.split(':') } }

or

str = File.read("/etc/passwd")
a = str.map { |line| line.split(':') }

That is: the contract for map is to run through an Enumerable and build the
results into an Array. It is not intended to run through an Enumerable and
to append the results into a new instance of whatever class that object
originally was.

It may not even be possible to create a new instance of that class, if the
initialize method requires arguments.

Aside: I suppose you could have such a pattern if you explicitly provided
the object to append to.

module Enumerable
def into(target=[], &blk)
blk ||= lambda { |e| e }
each { |e| target << blk[e] }
target
end
end

src = "one\ntwo\nthree\n"
p src.into([])
p src.into("") { |e| "*#{e}" }
src.into($stdout) { |e| e.upcase } # process a line at a time

data = ["one\n", "two\n", "three\n"]
p data.into("")

Perhaps even map itself could take the thing to write 'into' as an argument.

You could also argue that Hash#update should accept any Enumerable as its
argument, so you could write

a = [[1,:one], [2,:two], [3,:three]]
h = {}.update(a)

to convert an associative array to a hash.

But I've never needed either construct. Probably these things belong in the
Facets library, if not there already. There is value in minimising the
amount of magic in the core language, and there's a lot there already.

B.

=end

#2 Updated by Brian Candler almost 7 years ago

=begin

Not this case. String is no longer Enumerable.

Thank you, my mistake. I'm not chasing the moving target of 1.9 until it
stabilises. And even then I suspect I'll stick with 1.8.6 for quite a while,
rather than learn new new magic and syntax in 1.9/2.0.

Now if 1.9 had removed magic or syntax from 1.8, I'd be much more
interested. (For example, if it had eliminated the semantic distinctions
between method calls, lambda calls and Proc calls). Then I could garbage
collect some space in my brain.

But I guess that's an admission that I'm not qualified to talk on ruby-core,
so I'll shut up now :-)

Cheers,

Brian.

=end

#3 Updated by Brian Candler over 6 years ago

=begin

If you are a well practiced user of Ruby, I think that qualifies you.

Thank you. What I meant was, I can hardly comment on core development (1.9)
if I've been studiously avoiding it in favour of 1.8.

=end

#4 Updated by Koichi Sasada over 6 years ago

  • Assignee set to Yukihiro Matsumoto

=begin

=end

#5 Updated by Yukihiro Matsumoto over 6 years ago

  • Status changed from Open to Rejected

=begin
The usefulness and detailed behavior of the proposal is not cleared.
So we have to reject this proposal this time. Maybe next time.
=end

#6 Updated by Yukihiro Matsumoto over 6 years ago

=begin
Hi,

In message "Re: [Feature #474] Hash#<<"
on Sat, 23 Aug 2008 05:35:06 +0900, Anonymous redmine@ruby-lang.org writes:

|To recap, the idea is:
|
| h = Hash.new
| h << [:a, 1]
| h << [:b, 2]
| h #=> {:a=>1, :b=>2}
|
|This creates a polymorphism between associative arrays and hashes, which ultimately could be useful to mixins. And now that Hash supports insertion order too, it makes further sense. There was a particular usecase exemplified in the fore-mentioned thread. But since I can't find it I can't show it here. I just recall thinking it was compelling. Perhaps other's can recall?

Unlike Smalltalk's Dictionaries, Hashes in Ruby does not provide the
illusion of being sequence of association. So the proposed new method
makes less sense in Ruby.

Besides that, Associative Arrays (which has normal array methods) and
hashes cannot behave polymorphic.

                        matz.

=end

Also available in: Atom PDF