Hi,
I got recently an unexpected result using Array#join.
In my thoughts, Array#join is sth like adding the separator between every
element#to_s.
That is what seems to happen when there is no any #to_a method defined in an
element:
For example,
class N < Struct.new(:n)
def to_s
'to_s'
end
end
[N.new(2), N.new(3)].join(' ') #=> "2 3" and not "to_s to_s"
This is due to Struct::new that defines #to_a that return an Array of
instance variables (here :n).
That's quite annoying, because you would expect when you're defining to_s to
be the only usual String representation.
The only way to edit that behavior without changing Array#join, is to
"undef_method :to_a", not very nice ...
or to use ary.map(&:to_s).join, very redundant.
Shouldn't Array#join looks like:
class Array
def join(sep = $,)
sep = '' if sep.nil?
s = ""
self.each_with_index { |e, i|
s << e.to_s
s << sep unless i == size-1
}
s
end
end
Why is it this 'look' to element#to_a ? is that really interesting? when?
Maybe when you use [[1],[2,3]].join #=> "123" ? Then we should look for
#to_ary, not #to_a
Regards,
B.D.
I got "to_s to_s" in 1.8.6, 1.8.7, and 1.9.1
···
On Sun, Feb 28, 2010 at 12:53 PM, Benoit Daloze <eregontp@gmail.com> wrote:
Hi,
I got recently an unexpected result using Array#join.
In my thoughts, Array#join is sth like adding the separator between every
element#to_s.
That is what seems to happen when there is no any #to_a method defined in
an
element:
For example,
class N < Struct.new(:n)
def to_s
'to_s'
end
end
[N.new(2), N.new(3)].join(' ') #=> "2 3" and not "to_s to_s"
> Hi,
>
> I got recently an unexpected result using Array#join.
>
> In my thoughts, Array#join is sth like adding the separator between every
> element#to_s.
>
> That is what seems to happen when there is no any #to_a method defined in
> an
> element:
>
> For example,
> class N < Struct.new(:n)
> def to_s
> 'to_s'
> end
> end
>
> [N.new(2), N.new(3)].join(' ') #=> "2 3" and not "to_s to_s"
>
I got "to_s to_s" in 1.8.6, 1.8.7, and 1.9.1
Me:
irb for ruby-1.9.2-r26764
class N < Struct.new(:n)
def to_s
'to_s'
end
end
=> nil
[N.new(2), N.new(3)].join(' ')
=> "2 3"
irb for ruby-1.8.7-p249
class N < Struct.new(:n)
def to_s
'to_s'
end
end
=> nil
[N.new(2), N.new(3)].join(' ')
=> "to_s to_s"
So this would be only 1.9.2 behavior, but why on world this changed? It has
such bad side-effect in this case.
···
On 1 March 2010 04:25, Josh Cheek <josh.cheek@gmail.com> wrote:
On Sun, Feb 28, 2010 at 12:53 PM, Benoit Daloze <eregontp@gmail.com> > wrote:
---
Also, while playing with Array, using Array#&, I saw it look on #eql? and
#hash methods. These two methods are relative to Hash usually, I didn't
expect methods of Array to depends of them.
A surprising result to me:
irb for ruby-1.9.2-r26764
[1,2]&[2]
=> [2]
class N
def initialize(n)
@n = n
end
attr_reader :n
def == o
@n == o.n
end
end
=> nil
[N.new(1),N.new(2)]&[N.new(2)]
=> # instead of [#<N:.. @n=2>]
So this would be only 1.9.2 behavior, but why on world this changed? It has
such bad side-effect in this case.
Maybe #flatten's functionality was extended to also include objects
that implement to_a because to_a has been removed from Object in
1.9...
Also, while playing with Array, using Array#&, I saw it look on #eql? and
#hash methods. These two methods are relative to Hash usually, I didn't
expect methods of Array to depends of them.
Learn something new every day. 
Kind regards
robert
···
2010/3/1 Benoit Daloze <eregontp@gmail.com>:
--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/
Also, while playing with Array, using Array#&, I saw it look on #eql? and
#hash methods. These two methods are relative to Hash usually, I didn't
expect methods of Array to depends of them.
It's because the efficient (O(1)) implementation of Array#& requires
creating a temporary hash (or 2?) internally. However, this would seem
to be an internal detail and callers should not have to know about it,
as your example (quoted below) demonstrates.
···
On 3/1/10, Benoit Daloze <eregontp@gmail.com> wrote:
A surprising result to me:
irb for ruby-1.9.2-r26764
[1,2]&[2]
=> [2]
class N
def initialize(n)
@n = n
end
attr_reader :n
def == o
@n == o.n
end
end
=> nil
[N.new(1),N.new(2)]&[N.new(2)]
=> # instead of [#<N:.. @n=2>]