Behaviour of Enumerables reject vs. select mixed into Hash

Discussion in 'Ruby' started by Alexander Presber, Jun 20, 2007.

  1. Hello everybody,

    Could you please take a look at the result of the following statements:

    irb(main):001:0> a = {'foo' => 'bar', 'baz' => 'qux'}
    => {"baz"=>"qux", "foo"=>"bar"}

    irb(main):002:0> a.reject{|k,v| k=='foo' }
    => {"baz"=>"qux"}

    irb(main):003:0> a.select{|k,v| k=='baz' }
    => [["baz", "qux"]]

    The result of the reject statement is clearly sensible: the original
    hash minus the element with the key 'foo'.
    But what about select? Shouldn't it return the same hash (instead of
    an array of key-value pairs)?

    Thanks for any comments
    Sincerely yours
    Alexander Presber
     
    Alexander Presber, Jun 20, 2007
    #1
    1. Advertising

  2. Alexander Presber

    Trans Guest

    On Jun 20, 3:21 pm, Alexander Presber <> wrote:
    > Hello everybody,
    >
    > Could you please take a look at the result of the following statements:
    >
    > irb(main):001:0> a = {'foo' => 'bar', 'baz' => 'qux'}
    > => {"baz"=>"qux", "foo"=>"bar"}
    >
    > irb(main):002:0> a.reject{|k,v| k=='foo' }
    > => {"baz"=>"qux"}
    >
    > irb(main):003:0> a.select{|k,v| k=='baz' }
    > => [["baz", "qux"]]
    >
    > The result of the reject statement is clearly sensible: the original
    > hash minus the element with the key 'foo'.
    > But what about select? Shouldn't it return the same hash (instead of
    > an array of key-value pairs)?


    I have to concur. I've never liked that. You'd think there'd be some
    way to have Enumerable act in accordance with the class it is
    effecting, rather then dropping to the "LCD" --an array.

    T.
     
    Trans, Jun 20, 2007
    #2
    1. Advertising

  3. Alexander Presber

    Robert Dober Guest

    On 6/21/07, Trans <> wrote:
    >
    >
    > On Jun 20, 3:21 pm, Alexander Presber <> wrote:
    > > Hello everybody,
    > >
    > > Could you please take a look at the result of the following statements:
    > >
    > > irb(main):001:0> a = {'foo' => 'bar', 'baz' => 'qux'}
    > > => {"baz"=>"qux", "foo"=>"bar"}
    > >
    > > irb(main):002:0> a.reject{|k,v| k=='foo' }
    > > => {"baz"=>"qux"}
    > >
    > > irb(main):003:0> a.select{|k,v| k=='baz' }
    > > => [["baz", "qux"]]
    > >
    > > The result of the reject statement is clearly sensible: the original
    > > hash minus the element with the key 'foo'.
    > > But what about select? Shouldn't it return the same hash (instead of
    > > an array of key-value pairs)?

    >
    > I have to concur. I've never liked that. You'd think there'd be some
    > way to have Enumerable act in accordance with the class it is
    > effecting, rather then dropping to the "LCD" --an array.


    So do I, Do you happen to have some remedies for this in Facets?
    I am trying to unify such things in my library, but I am not building
    something even close to Factes[1], however if you are interested in
    some peaces let me know.

    Cheers
    Robert

    [1] because than I would just use Facets which is really great, but I
    want a small library and I want magic dot notation, which are liked by
    few only :(

    R.
    >
    > T.
    >
    >
    >



    --
    You see things; and you say Why?
    But I dream things that never were; and I say Why not?
    -- George Bernard Shaw
     
    Robert Dober, Jun 21, 2007
    #3
  4. >> Hello everybody,
    >>
    >> Could you please take a look at the result of the following
    >> statements:
    >>
    >> irb(main):001:0> a = {'foo' => 'bar', 'baz' => 'qux'}
    >> => {"baz"=>"qux", "foo"=>"bar"}
    >>
    >> irb(main):002:0> a.reject{|k,v| k=='foo' }
    >> => {"baz"=>"qux"}
    >>
    >> irb(main):003:0> a.select{|k,v| k=='baz' }
    >> => [["baz", "qux"]]
    >>
    >> The result of the reject statement is clearly sensible: the original
    >> hash minus the element with the key 'foo'.
    >> But what about select? Shouldn't it return the same hash (instead of
    >> an array of key-value pairs)?

    >
    > I have to concur. I've never liked that. You'd think there'd be some
    > way to have Enumerable act in accordance with the class it is
    > effecting, rather then dropping to the "LCD" --an array.


    Absolutely.
    But the most baffling to me is, that it does not even act
    _consistently_, see my original examples.
    From a logical point of view (or at least the principle of least
    surprise), selecting some elements should be identical
    to dropping the others.

    Is there anybody who can explain, why it had to be implemented that way?
    Is there any chance of that getting changed in the future?

    Sincerely yours,
    Alexander Presber
     
    Alexander Presber, Jun 21, 2007
    #4
  5. On 21.06.2007 11:06, Alexander Presber wrote:
    >>> Hello everybody,
    >>>
    >>> Could you please take a look at the result of the following statements:
    >>>
    >>> irb(main):001:0> a = {'foo' => 'bar', 'baz' => 'qux'}
    >>> => {"baz"=>"qux", "foo"=>"bar"}
    >>>
    >>> irb(main):002:0> a.reject{|k,v| k=='foo' }
    >>> => {"baz"=>"qux"}
    >>>
    >>> irb(main):003:0> a.select{|k,v| k=='baz' }
    >>> => [["baz", "qux"]]
    >>>
    >>> The result of the reject statement is clearly sensible: the original
    >>> hash minus the element with the key 'foo'.
    >>> But what about select? Shouldn't it return the same hash (instead of
    >>> an array of key-value pairs)?

    >>
    >> I have to concur. I've never liked that. You'd think there'd be some
    >> way to have Enumerable act in accordance with the class it is
    >> effecting, rather then dropping to the "LCD" --an array.

    >
    > Absolutely.
    > But the most baffling to me is, that it does not even act
    > _consistently_, see my original examples.
    > From a logical point of view (or at least the principle of least
    > surprise), selecting some elements should be identical
    > to dropping the others.
    >
    > Is there anybody who can explain, why it had to be implemented that way?
    > Is there any chance of that getting changed in the future?


    The #select in Enumerable can only return a "general" type - in this
    case an Array. Making Enumerable depend on the class is not a good idea
    IMHO. Maybe an implementation using #dup would help though...

    Of course Hash#select could act differently but that a) might hurt duck
    typing and b) could break existing code. Note that you can always do
    something like

    selected = a_hash.dup.delete_if {|k,v| ... }

    Kind regards

    robert
     
    Robert Klemme, Jun 21, 2007
    #5
  6. > On 21.06.2007 11:06, Alexander Presber wrote:
    >>>> Hello everybody,
    >>>>
    >>>> Could you please take a look at the result of the following
    >>>> statements:
    >>>>
    >>>> irb(main):001:0> a = {'foo' => 'bar', 'baz' => 'qux'}
    >>>> => {"baz"=>"qux", "foo"=>"bar"}
    >>>>
    >>>> irb(main):002:0> a.reject{|k,v| k=='foo' }
    >>>> => {"baz"=>"qux"}
    >>>>
    >>>> irb(main):003:0> a.select{|k,v| k=='baz' }
    >>>> => [["baz", "qux"]]
    >>>>
    >>>> The result of the reject statement is clearly sensible: the
    >>>> original
    >>>> hash minus the element with the key 'foo'.
    >>>> But what about select? Shouldn't it return the same hash
    >>>> (instead of
    >>>> an array of key-value pairs)?
    >>>
    >>> I have to concur. I've never liked that. You'd think there'd be some
    >>> way to have Enumerable act in accordance with the class it is
    >>> effecting, rather then dropping to the "LCD" --an array.

    >> Absolutely.
    >> But the most baffling to me is, that it does not even act
    >> _consistently_, see my original examples.
    >> From a logical point of view (or at least the principle of least
    >> surprise), selecting some elements should be identical
    >> to dropping the others.
    >> Is there anybody who can explain, why it had to be implemented
    >> that way?
    >> Is there any chance of that getting changed in the future?

    >
    > The #select in Enumerable can only return a "general" type - in
    > this case an Array. Making Enumerable depend on the class is not a
    > good idea IMHO. Maybe an implementation using #dup would help
    > though...
    >
    > Of course Hash#select could act differently but that a) might hurt
    > duck typing and b) could break existing code. Note that you can
    > always do something like
    >
    > selected = a_hash.dup.delete_if {|k,v| ... }
    >
    > Kind regards
    >
    > robert
    >
    >
     
    Alexander Presber, Jun 21, 2007
    #6
  7. Am 21.06.2007 um 11:20 schrieb Robert Klemme:

    > On 21.06.2007 11:06, Alexander Presber wrote:
    >>>> Hello everybody,
    >>>>
    >>>> Could you please take a look at the result of the following
    >>>> statements:
    >>>>
    >>>> irb(main):001:0> a = {'foo' => 'bar', 'baz' => 'qux'}
    >>>> => {"baz"=>"qux", "foo"=>"bar"}
    >>>>
    >>>> irb(main):002:0> a.reject{|k,v| k=='foo' }
    >>>> => {"baz"=>"qux"}
    >>>>
    >>>> irb(main):003:0> a.select{|k,v| k=='baz' }
    >>>> => [["baz", "qux"]]
    >>>>
    >>>> The result of the reject statement is clearly sensible: the
    >>>> original
    >>>> hash minus the element with the key 'foo'.
    >>>> But what about select? Shouldn't it return the same hash
    >>>> (instead of
    >>>> an array of key-value pairs)?
    >>>
    >>> I have to concur. I've never liked that. You'd think there'd be some
    >>> way to have Enumerable act in accordance with the class it is
    >>> effecting, rather then dropping to the "LCD" --an array.

    >> Absolutely.
    >> But the most baffling to me is, that it does not even act
    >> _consistently_, see my original examples.
    >> From a logical point of view (or at least the principle of least
    >> surprise), selecting some elements should be identical
    >> to dropping the others.
    >> Is there anybody who can explain, why it had to be implemented
    >> that way?
    >> Is there any chance of that getting changed in the future?


    Sorry for the empty post, to much clicking without thinking.

    > The #select in Enumerable can only return a "general" type - in
    > this case an Array.


    I see, but isn't that restating the problem?

    Even though "Programming Ruby" states: [snip] Enumerable#reject:
    returns an array for all elements of enumObj for which block is false
    (see also Enumerable#find_all) [/snip],
    reject _respects_ the class it acts upon in returning a _hash_, not
    an array.
    Not so select.
    Do you see the inconsistency?

    > Making Enumerable depend on the class is not a good idea IMHO.
    > Maybe an implementation using #dup would help though...


    Could you please elaborate into that? I do not understand.

    > Of course Hash#select could act differently but that a) might hurt
    > duck typing


    I fail to see why, could you give an example?

    > and b) could break existing code.


    That is true.

    > Note that you can always do something like
    >
    > selected = a_hash.dup.delete_if {|k,v| ... }


    Not quite. hsh.dup.delete_if is equivalent to hsh.reject, and reject
    works just fine.
    And of course I could always use Hash#reject (or hash#delete_if for
    that matter) instead of Hash#select by just negating the block.

    But the problem I see lies within the inconsistent return type of
    Hash#select.

    I could imagine if one wanted to change that behaviour, the "mixee"
    class would have to provide certain capabilities to be able to get
    Enumerable#select, much like objects have to provide an
    implementation of <=> to get min and max.

    > Kind regards
    >
    > robert


    Yours truly,
    Alexander
     
    Alexander Presber, Jun 21, 2007
    #7
  8. Alexander Presber

    Guest

    Hi --

    On Thu, 21 Jun 2007, Alexander Presber wrote:

    > Am 21.06.2007 um 11:20 schrieb Robert Klemme:
    >
    >> On 21.06.2007 11:06, Alexander Presber wrote:
    >>>>> Hello everybody,
    >>>>>
    >>>>> Could you please take a look at the result of the following statements:
    >>>>>
    >>>>> irb(main):001:0> a = {'foo' => 'bar', 'baz' => 'qux'}
    >>>>> => {"baz"=>"qux", "foo"=>"bar"}
    >>>>>
    >>>>> irb(main):002:0> a.reject{|k,v| k=='foo' }
    >>>>> => {"baz"=>"qux"}
    >>>>>
    >>>>> irb(main):003:0> a.select{|k,v| k=='baz' }
    >>>>> => [["baz", "qux"]]
    >>>>>
    >>>>> The result of the reject statement is clearly sensible: the original
    >>>>> hash minus the element with the key 'foo'.
    >>>>> But what about select? Shouldn't it return the same hash (instead of
    >>>>> an array of key-value pairs)?
    >>>>
    >>>> I have to concur. I've never liked that. You'd think there'd be some
    >>>> way to have Enumerable act in accordance with the class it is
    >>>> effecting, rather then dropping to the "LCD" --an array.
    >>> Absolutely.
    >>> But the most baffling to me is, that it does not even act _consistently_,
    >>> see my original examples.
    >>> From a logical point of view (or at least the principle of least
    >>> surprise), selecting some elements should be identical
    >>> to dropping the others.
    >>> Is there anybody who can explain, why it had to be implemented that way?
    >>> Is there any chance of that getting changed in the future?

    >
    > Sorry for the empty post, to much clicking without thinking.
    >
    >> The #select in Enumerable can only return a "general" type - in this case
    >> an Array.

    >
    > I see, but isn't that restating the problem?


    I think Robert's point is that nothing other than a general type makes
    sense. For example, if you select from an IO stream, you don't expect
    another IO stream.

    > Even though "Programming Ruby" states: [snip] Enumerable#reject: returns an
    > array for all elements of enumObj for which block is false (see also
    > Enumerable#find_all) [/snip],
    > reject _respects_ the class it acts upon in returning a _hash_, not an array.
    > Not so select.
    > Do you see the inconsistency?


    Hash overrides Enumerable#reject. I'm not sure why, except possibly
    because of the relation between reject and delete_if.

    >> Making Enumerable depend on the class is not a good idea IMHO. Maybe an
    >> implementation using #dup would help though...

    >
    > Could you please elaborate into that? I do not understand.
    >
    >> Of course Hash#select could act differently but that a) might hurt duck
    >> typing

    >
    > I fail to see why, could you give an example?


    Anything that depends on the output having array-like behaviors:

    selected = enum.select(&select_block).flatten


    David

    --
    * Books:
    RAILS ROUTING (new! http://www.awprofessional.com/title/0321509242)
    RUBY FOR RAILS (http://www.manning.com/black)
    * Ruby/Rails training
    & consulting: Ruby Power and Light, LLC (http://www.rubypal.com)
     
    , Jun 21, 2007
    #8
  9. Alexander Presber

    Robert Dober Guest

    On 6/21/07, <> wrote:
    > Hi --
    >
    >
    > >
    > > I fail to see why, could you give an example?

    >
    > Anything that depends on the output having array-like behaviors:
    >
    > selected = enum.select(&select_block).flatten

    That is ok, but we are complaining about

    hash.select

    Please note that the notion of Enumerable#select is erroneous in this
    thread, sorry for being blunt Alexander but you were talking about
    Hash#select the whole time.

    I think this would be a picture case for breaking backwards
    compatibility in Ruby2.0
    Hash#select --> returning a Hash
    and we would live in a better world ;)
    unless you do not like it of course.

    In other words it might be interesting to know if people like this
    behavior without thinking about backwards compatibility or
    implementation details.

    Robert
    --
    You see things; and you say Why?
    But I dream things that never were; and I say Why not?
    -- George Bernard Shaw
     
    Robert Dober, Jun 21, 2007
    #9
  10. Am 21.06.2007 um 12:08 schrieb :

    > Hi --
    >
    > On Thu, 21 Jun 2007, Alexander Presber wrote:
    >
    >> Am 21.06.2007 um 11:20 schrieb Robert Klemme:
    >>
    >>> On 21.06.2007 11:06, Alexander Presber wrote:
    >>>>>> Hello everybody,
    >>>>>> Could you please take a look at the result of the following
    >>>>>> statements:
    >>>>>> irb(main):001:0> a = {'foo' => 'bar', 'baz' => 'qux'}
    >>>>>> => {"baz"=>"qux", "foo"=>"bar"}
    >>>>>> irb(main):002:0> a.reject{|k,v| k=='foo' }
    >>>>>> => {"baz"=>"qux"}
    >>>>>> irb(main):003:0> a.select{|k,v| k=='baz' }
    >>>>>> => [["baz", "qux"]]
    >>>>>> The result of the reject statement is clearly sensible: the
    >>>>>> original
    >>>>>> hash minus the element with the key 'foo'.
    >>>>>> But what about select? Shouldn't it return the same hash
    >>>>>> (instead of
    >>>>>> an array of key-value pairs)?
    >>>>> I have to concur. I've never liked that. You'd think there'd be
    >>>>> some
    >>>>> way to have Enumerable act in accordance with the class it is
    >>>>> effecting, rather then dropping to the "LCD" --an array.
    >>>> Absolutely.
    >>>> But the most baffling to me is, that it does not even act
    >>>> _consistently_, see my original examples.
    >>>> From a logical point of view (or at least the principle of least
    >>>> surprise), selecting some elements should be identical
    >>>> to dropping the others.
    >>>> Is there anybody who can explain, why it had to be implemented
    >>>> that way?
    >>>> Is there any chance of that getting changed in the future?

    >>
    >> Sorry for the empty post, to much clicking without thinking.
    >>
    >>> The #select in Enumerable can only return a "general" type - in
    >>> this case an Array.

    >>
    >> I see, but isn't that restating the problem?

    >
    > I think Robert's point is that nothing other than a general type makes
    > sense. For example, if you select from an IO stream, you don't expect
    > another IO stream.


    Mhm. I thought IO#select is mixed in from the module Kernel, not
    Enumerable. In this case, select can return whatever Kernel considers
    appropriate.

    I would like to think of the Enumerable mixin as an interface,
    describing the general concept of "enumerability".
    Rejecting and selecting certain elements of an enumerable set
    certainly belong to this concept.

    As I see it, a general recipe for selecting would be:
    1) iterate (hence the need for enumerability) vfer the given set and
    check the return value of the block for each element.
    2) if true, keep, otherwise drop
    3) return the resulting set, keeping all other properties (including
    class) intact

    Rejecting is just the opposite for 2).

    >> Even though "Programming Ruby" states: [snip] Enumerable#reject:
    >> returns an array for all elements of enumObj for which block is
    >> false (see also Enumerable#find_all) [/snip],
    >> reject _respects_ the class it acts upon in returning a _hash_,
    >> not an array.
    >> Not so select.
    >> Do you see the inconsistency?

    >
    > Hash overrides Enumerable#reject. I'm not sure why, except possibly
    > because of the relation between reject and delete_if.


    >>> Making Enumerable depend on the class is not a good idea IMHO.
    >>> Maybe an implementation using #dup would help though...

    >>
    >> Could you please elaborate into that? I do not understand.
    >>
    >>> Of course Hash#select could act differently but that a) might
    >>> hurt duck typing

    >>
    >> I fail to see why, could you give an example?

    >
    > Anything that depends on the output having array-like behaviors:
    >
    > selected = enum.select(&select_block).flatten


    I don't get what that has to do with duck typing.

    The possibility to _flatten_ something requires it to be an Array-
    duck, not an Enumerable-duck. That is why flatten is part of Array.
    Nobody should expect the result of Enumerable#select to be flattenable.

    If however there is a sensible way to make the Enumerable an Array
    (in order to flatten it), you should go:

    selected = enum.select(&select_block).to_a.flatten

    (note the to_a)

    Sincerely yours,
    Alex
     
    Alexander Presber, Jun 21, 2007
    #10
  11. Alexander Presber

    Guest

    Hi --

    On Thu, 21 Jun 2007, Robert Dober wrote:

    > On 6/21/07, <> wrote:
    >> Hi --
    >>
    >>
    >> >
    >> > I fail to see why, could you give an example?

    >>
    >> Anything that depends on the output having array-like behaviors:
    >>
    >> selected = enum.select(&select_block).flatten

    > That is ok, but we are complaining about
    >
    > hash.select
    >
    > Please note that the notion of Enumerable#select is erroneous in this
    > thread, sorry for being blunt Alexander but you were talking about
    > Hash#select the whole time.


    Yes, but making a special case of Hash, as opposed to other
    enumerables, is exactly what breaks duck typing. I would actually
    prefer to see Hash#reject return an array.

    > I think this would be a picture case for breaking backwards
    > compatibility in Ruby2.0
    > Hash#select --> returning a Hash
    > and we would live in a better world ;)
    > unless you do not like it of course.
    >
    > In other words it might be interesting to know if people like this
    > behavior without thinking about backwards compatibility or
    > implementation details.


    I like having arrays be the "common currency" of select operations. I
    don't think there's anything that you're prevented from doing as long
    as that's the case.


    David

    --
    * Books:
    RAILS ROUTING (new! http://www.awprofessional.com/title/0321509242)
    RUBY FOR RAILS (http://www.manning.com/black)
    * Ruby/Rails training
    & consulting: Ruby Power and Light, LLC (http://www.rubypal.com)
     
    , Jun 21, 2007
    #11
  12. On 6/21/07, <> wrote:
    > Hi --
    >
    > On Thu, 21 Jun 2007, Robert Dober wrote:
    >
    > > On 6/21/07, <> wrote:
    > >> Hi --
    > >>
    > >>
    > >> >
    > >> > I fail to see why, could you give an example?
    > >>
    > >> Anything that depends on the output having array-like behaviors:
    > >>
    > >> selected = enum.select(&select_block).flatten

    > > That is ok, but we are complaining about
    > >
    > > hash.select
    > >
    > > Please note that the notion of Enumerable#select is erroneous in this
    > > thread, sorry for being blunt Alexander but you were talking about
    > > Hash#select the whole time.

    >
    > Yes, but making a special case of Hash, as opposed to other
    > enumerables, is exactly what breaks duck typing. I would actually
    > prefer to see Hash#reject return an array.
    >
    > > I think this would be a picture case for breaking backwards
    > > compatibility in Ruby2.0
    > > Hash#select --> returning a Hash
    > > and we would live in a better world ;)
    > > unless you do not like it of course.
    > >
    > > In other words it might be interesting to know if people like this
    > > behavior without thinking about backwards compatibility or
    > > implementation details.

    >
    > I like having arrays be the "common currency" of select operations. I
    > don't think there's anything that you're prevented from doing as long
    > as that's the case.
    >


    So what, making #reject return an Array as well?

    >
    > David
    >
    > --
    > * Books:
    > RAILS ROUTING (new! http://www.awprofessional.com/title/0321509242)
    > RUBY FOR RAILS (http://www.manning.com/black)
    > * Ruby/Rails training
    > & consulting: Ruby Power and Light, LLC (http://www.rubypal.com)
    >
    >
     
    Michael Fellinger, Jun 21, 2007
    #12
  13. Alexander Presber

    Guest

    Hi --

    On Thu, 21 Jun 2007, Alexander Presber wrote:

    > I would like to think of the Enumerable mixin as an interface, describing the
    > general concept of "enumerability".
    > Rejecting and selecting certain elements of an enumerable set certainly
    > belong to this concept.
    >
    > As I see it, a general recipe for selecting would be:
    > 1) iterate (hence the need for enumerability) vfer the given set and check
    > the return value of the block for each element.
    > 2) if true, keep, otherwise drop
    > 3) return the resulting set, keeping all other properties (including class)
    > intact


    The question, though, is the representation of the "set". Any class
    that mixes in Enumerable and defines #each can have a select
    operation, and there's no constraint that says that such a class has
    to be a collection. So you can't guarantee that the class provides a
    container in which an instance can return a smaller version of itself.

    >>>> Of course Hash#select could act differently but that a) might hurt duck
    >>>> typing
    >>>
    >>> I fail to see why, could you give an example?

    >>
    >> Anything that depends on the output having array-like behaviors:
    >>
    >> selected = enum.select(&select_block).flatten

    >
    > I don't get what that has to do with duck typing.
    >
    > The possibility to _flatten_ something requires it to be an Array-duck, not
    > an Enumerable-duck. That is why flatten is part of Array.
    > Nobody should expect the result of Enumerable#select to be flattenable.


    Well, that's what we're discussing :) I expect #select to return an
    array, so it's flattenable. But now I think we're going in circles.


    David

    --
    * Books:
    RAILS ROUTING (new! http://www.awprofessional.com/title/0321509242)
    RUBY FOR RAILS (http://www.manning.com/black)
    * Ruby/Rails training
    & consulting: Ruby Power and Light, LLC (http://www.rubypal.com)
     
    , Jun 21, 2007
    #13
  14. Alexander Presber

    Guest

    Hi --

    On Thu, 21 Jun 2007, Michael Fellinger wrote:

    > On 6/21/07, <> wrote:
    >> Hi --
    >>
    >> On Thu, 21 Jun 2007, Robert Dober wrote:
    >>
    >> > On 6/21/07, <> wrote:
    >> >> Hi --
    >> >>
    >> >>
    >> >> >
    >> >> > I fail to see why, could you give an example?
    >> >>
    >> >> Anything that depends on the output having array-like behaviors:
    >> >>
    >> >> selected = enum.select(&select_block).flatten
    >> > That is ok, but we are complaining about
    >> >
    >> > hash.select
    >> >
    >> > Please note that the notion of Enumerable#select is erroneous in this
    >> > thread, sorry for being blunt Alexander but you were talking about
    >> > Hash#select the whole time.

    >>
    >> Yes, but making a special case of Hash, as opposed to other
    >> enumerables, is exactly what breaks duck typing. I would actually
    >> prefer to see Hash#reject return an array.
    >>
    >> > I think this would be a picture case for breaking backwards
    >> > compatibility in Ruby2.0
    >> > Hash#select --> returning a Hash
    >> > and we would live in a better world ;)
    >> > unless you do not like it of course.
    >> >
    >> > In other words it might be interesting to know if people like this
    >> > behavior without thinking about backwards compatibility or
    >> > implementation details.

    >>
    >> I like having arrays be the "common currency" of select operations. I
    >> don't think there's anything that you're prevented from doing as long
    >> as that's the case.
    >>

    >
    > So what, making #reject return an Array as well?


    Yes -- see about 18 lines up :)


    David

    --
    * Books:
    RAILS ROUTING (new! http://www.awprofessional.com/title/0321509242)
    RUBY FOR RAILS (http://www.manning.com/black)
    * Ruby/Rails training
    & consulting: Ruby Power and Light, LLC (http://www.rubypal.com)
     
    , Jun 21, 2007
    #14
  15. Alexander Presber

    Robert Dober Guest

    On 6/21/07, <> wrote:
    > Hi --
    >
    > On Thu, 21 Jun 2007, Robert Dober wrote:
    >


    >
    > I like having arrays be the "common currency" of select operations.
    > don't think there's anything that you're prevented from doing as long
    > as that's the case.


    Sure there is, I do not want to convert Arrays back to Hashes all the
    time -- and I am not talking performance.

    And why do I have Hash#select anyway in that case? I could very well
    use Enumerable#select if I wanted the behavior you have described.

    BTW Hash#to_a will not be deprecated I guess ;)

    Robert
    --
    You see things; and you say Why?
    But I dream things that never were; and I say Why not?
    -- George Bernard Shaw
     
    Robert Dober, Jun 21, 2007
    #15

  16. >> The possibility to _flatten_ something requires it to be an Array-
    >> duck, not an Enumerable-duck. That is why flatten is part of Array.
    >> Nobody should expect the result of Enumerable#select to be
    >> flattenable.

    >
    > Well, that's what we're discussing :) I expect #select to return an
    > array, so it's flattenable. But now I think we're going in circles.


    Why, of all possibities, an Array? Why not an Hash or any other class
    that mixes in Enumerable?
    As I wanted to point out: The Array class is in no way a special
    Enumerable, but it is treated special by being the return type of
    some (!) Enumerable operations.

    See, not all Enumerables _are_ Arrays, it's the other way around.
    It may not make much of a difference in every day coding, but if you
    don't keep the two apart, then why not drop Enumerable alltogether
    and always mix Array in instead?
    There should be a reason Enumerable was introduced as opposed to
    include it's functionality in Array?

    Yours,
    Alexander
     
    Alexander Presber, Jun 21, 2007
    #16
  17. Alexander Presber

    Guest

    Hi --

    On Thu, 21 Jun 2007, Alexander Presber wrote:

    >
    >>> The possibility to _flatten_ something requires it to be an Array-duck,
    >>> not an Enumerable-duck. That is why flatten is part of Array.
    >>> Nobody should expect the result of Enumerable#select to be flattenable.

    >>
    >> Well, that's what we're discussing :) I expect #select to return an
    >> array, so it's flattenable. But now I think we're going in circles.

    >
    > Why, of all possibities, an Array? Why not an Hash or any other class that
    > mixes in Enumerable?
    > As I wanted to point out: The Array class is in no way a special Enumerable,
    > but it is treated special by being the return type of some (!) Enumerable
    > operations.
    >
    > See, not all Enumerables _are_ Arrays, it's the other way around.
    > It may not make much of a difference in every day coding, but if you don't
    > keep the two apart, then why not drop Enumerable alltogether and always mix
    > Array in instead?
    > There should be a reason Enumerable was introduced as opposed to include it's
    > functionality in Array?


    But its functionality is only in Array because Array mixes in
    Enumerable.


    David

    --
    * Books:
    RAILS ROUTING (new! http://www.awprofessional.com/title/0321509242)
    RUBY FOR RAILS (http://www.manning.com/black)
    * Ruby/Rails training
    & consulting: Ruby Power and Light, LLC (http://www.rubypal.com)
     
    , Jun 21, 2007
    #17
  18. On Jun 21, 5:37 am, wrote:
    > Yes, but making a special case of Hash, as opposed to other
    > enumerables, is exactly what breaks duck typing. I would actually
    > prefer to see Hash#reject return an array.
    >
    > I like having arrays be the "common currency" of select operations. I
    > don't think there's anything that you're prevented from doing as long
    > as that's the case.
    >
    > David


    The inconsistency of return values between Hash#reject vs. Hash#select
    has bothered me for a long time. Above all, I'd want this to be
    consistent, but unlike you (and I believe like the majority), I'd like
    both to return a Hash.

    I'm not really sure how duck typing even enters into it as a serious
    concern. The blocks given to reject/select are different based on the
    Enumerable type. Consider:

    irb(main):017:0> %w{red green blue}.select { |elem| elem.length > 4 }
    => ["green"]
    irb(main):018:0> {:red => true, :green => true, :blue => true}.select
    { |elem| elem.length > 4 }
    (irb):18: warning: multiple values for a block parameter (2 for 1)
    from (irb):18
    (irb):18: warning: multiple values for a block parameter (2 for 1)
    from (irb):18
    (irb):18: warning: multiple values for a block parameter (2 for 1)
    from (irb):18
    => []

    I get an Array from both, which is wonderful if I'm expecting an Array
    and I want to flatten the return value or do any other Array-specific
    things. The only problem is one array is useless and wrong.

    irb(main):019:0> {'red' => true, 'green' => true, 'blue' =>
    true}.select { |k,v| k.length > 4 }
    => [["green", true]]

    So now I've selected in a more sensible way. The problem here is I
    *knew* I was selecting from a Hash and wrote the block accordingly,
    but now I have this Array of two-element Arrays back.

    This is why I use reject with a negated block.

    --
    -yossef
     
    Yossef Mendelssohn, Jun 21, 2007
    #18
  19. Alexander Presber

    Robert Dober Guest

    On 6/21/07, Alexander Presber <> wrote:

    > There should be a reason Enumerable was introduced as opposed to
    > include it's functionality in Array?

    Alexander I agree with your POV, however maybe it would do this
    discussion some good to take one step back and look at the greater
    picture.

    Enumerable is a Mixin based on each and it implements methods like
    select, map etc by using the each interface of it's client class. It
    very often returns arrays than as it simply cannot do something
    different - without creating a revolutionary new concept like an
    Iterator but that is OffTopic

    You were complaining about Hash#select returning an Array. I complain
    about that too but it has nothing to do with Enumerable, Enumerable is
    not used, it is implemented in Hash itself.

    If we want to discuss if we like or dislike Hash#select returning an
    array we shall fear to mention Enumerable as it has nothing to do with
    it.
    As a matter of fact it would be ridiculous - you have explained that
    nicely yourself - to ask Enumerable to return Hashes.

    Cheers
    Robert

    --
    You see things; and you say Why?
    But I dream things that never were; and I say Why not?
    -- George Bernard Shaw
     
    Robert Dober, Jun 21, 2007
    #19
  20. Re: how to installed ruby in diffrent directory

    On 6/21/07, Ting Zhang <> wrote:
    > hi everyone,
    >
    > I am new to ruby, I want to installed ruby on workstation. But I am not a
    > super user and I don't have the access to /user/local. So I need to
    > change everything refer to /user/local/ to /home/fixpb.
    >
    > I try to find every file contain /user/local under ruby directory and
    > change them . I change the configure.h. I change everything I can find but
    > still doesn't work. I am really frustrated now and need your
    > help. Thanks!


    Why don't you do:
    ./configure --prefix=$HOME/ruby?

    --
    Felipe Contreras
     
    Felipe Contreras, Jun 21, 2007
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Ilmari Heikkinen
    Replies:
    12
    Views:
    192
    Glenn Parker
    Dec 17, 2004
  2. Erik Veenstra

    Hash#select and Hash#reject

    Erik Veenstra, Sep 21, 2005, in forum: Ruby
    Replies:
    0
    Views:
    136
    Erik Veenstra
    Sep 21, 2005
  3. Geert Fannes

    select! not present but reject! is

    Geert Fannes, Oct 5, 2005, in forum: Ruby
    Replies:
    43
    Views:
    486
    Ryan Leavengood
    Oct 9, 2005
  4. ara howard
    Replies:
    20
    Views:
    352
    Jeremy Hinegardner
    Apr 30, 2008
  5. Srijayanth Sridhar
    Replies:
    19
    Views:
    676
    David A. Black
    Jul 2, 2008
Loading...

Share This Page