Problem in using %:whatever in enumumerations

Discussion in 'Ruby' started by RichardOnRails, May 28, 2011.

  1. Hi,

    I'm on a Ruby self-improvement mission. Presently I working my way
    though all 47 of the Enumerable methods in Ruby 1.9.2. I composed the
    following:

    greek = %w{Alpha Beta Gamma}
    puts greek.all? { |s| s.length == 5 } # (correct) => false
    puts greek.all? { |s| (4..5).include? s.length } # (correct) => true
    puts greek.all?(&:length) # (programmer error) => true

    The last line is programmed incorrectly because I couldn't stick in
    the intended "5" in a syntactically correct way. Is the most
    effective way construction of a lamda/proc? If so, how?

    Thanks in advance,
    Richard:
     
    RichardOnRails, May 28, 2011
    #1
    1. Advertising

  2. RichardOnRails <> writes:

    > Hi,
    >
    > I'm on a Ruby self-improvement mission. Presently I working my way
    > though all 47 of the Enumerable methods in Ruby 1.9.2. I composed the
    > following:
    >
    > greek = %w{Alpha Beta Gamma}
    > puts greek.all? { |s| s.length == 5 } # (correct) => false
    > puts greek.all? { |s| (4..5).include? s.length } # (correct) => true
    > puts greek.all?(&:length) # (programmer error) => true
    >
    > The last line is programmed incorrectly because I couldn't stick in
    > the intended "5" in a syntactically correct way. Is the most
    > effective way construction of a lamda/proc? If so, how?
    >
    > Thanks in advance,
    > Richard:


    & converts method with a given name to Proc object, for example:

    &:length

    becomes:

    { |s| s.length }

    If that's not what you want (e.g. you need { |s| s.length == 5 }) -
    construct block yourself. There is no way to specify arguments when
    using &:length.
     
    Victor Deryagin, May 28, 2011
    #2
    1. Advertising

  3. On May 28, 2:20 am, Victor Deryagin <> wrote:

    Thanks for your response.

    > > greek = %w{Alpha Beta Gamma}
    > > puts greek.all? { |s| s.length == 5 }              #  (correct)  => false
    > > puts greek.all? { |s| (4..5).include? s.length }   #  (correct)  => true
    > > puts greek.all?(&:length)                      #  (programmer error)     => true


    > ... If that's not what you want (e.g. you need { |s| s.length == 5 })-
    > construct block yourself.


    I did construct the block myself in the first couple of examples
    (lines 2 & 3) but was searching (in line 4) for another way of
    expressing the requirement.

    I finally found a way to use a lambda in the following statements in
    place of line 4:

    lam = lambda { |item, len| item.length == 5 }
    puts greek.all? { |s| lam.call(s,5)} # (correct) => false

    Of course, the verbosity of this pair of statements is unsatisfying,
    so I'm still searching for succinct alternatives.

    Best wishes,
    Richard
     
    RichardOnRails, May 28, 2011
    #3
  4. On Sat, May 28, 2011 at 7:00 AM, RichardOnRails
    <> wrote:
    > On May 28, 2:20=C2=A0am, Victor Deryagin <> wrote:
    >
    > Thanks for your response.
    >
    >> > greek =3D %w{Alpha Beta Gamma}
    >> > puts greek.all? { |s| s.length =3D=3D 5 } =C2=A0 =C2=A0 =C2=A0 =C2=A0 =

    =C2=A0 =C2=A0 =C2=A0# =C2=A0(correct) =C2=A0=3D> false
    >> > puts greek.all? { |s| (4..5).include? s.length } =C2=A0 # =C2=A0(corre=

    ct) =C2=A0=3D> true
    >> > puts greek.all?(&:length) =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =

    =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0# =C2=A0(programmer error) =C2=A0 =C2=A0 =
    =3D> true
    >
    >> ... If that's not what you want (e.g. you need { |s| s.length =3D=3D 5 }=

    ) -
    >> construct block yourself.

    >
    > I did construct the block myself in the first couple of examples
    > (lines 2 & 3) but was searching (in line 4) for another way of
    > expressing the requirement.
    >
    > I finally found a way to use a lambda in the following statements in
    > place of line 4:
    >
    > lam =3D lambda { |item, len| item.length =3D=3D 5 }
    > puts greek.all? { |s| lam.call(s,5)} =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =

    =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0# =C2=A0(correct) =C2=A0=3D> false

    Note that the second argument to lambda is never used, as you've
    hardcoded 5 for the length to use for the test rather than using the
    second argument. If you want something where you can change the length
    to test for on different calls, replace the first line with:

    lam =3D lambda { |item, len| item.length =3D=3D len }

    >
    > Of course, the verbosity of this pair of statements is unsatisfying,
    > so I'm still searching for succinct alternatives.


    There isn't anything I can think of built in that's more succinct, but
    if this kind of test is common in your code, you can abstract part of
    it out to a library method on Enumerable and make the code more
    succinct and clear at the point of call.

    # elsewhere, extend Enumerable
    # (obvious parallels any_have?, one_has?, count_having, etc. could
    also be defined)

    module Enumerable
    def all_have?(attribute, value)
    all? { |item| item.__send__(attribute) =3D=3D value }
    end
    end

    # then, in the point you were working on

    greek.all_have? :length, 5
     
    Christopher Dicely, May 28, 2011
    #4
  5. On May 28, 3:08 pm, Christopher Dicely <> wrote:

    > module Enumerable
    > def all_have?(attribute, value)
    > all? { |item| item.__send__(attribute) == value }
    > end
    > end
    >
    > greek.all_have? :length, 5


    Hi Christopher,

    Philosophically, that's just the kind of thing I wanted (dynamic
    application of criteria) but didn't have the wit to describe it.

    As you saw in my post, I had the statement:
    puts greek.all? { |s| s.length == 5 }

    But if I had a number of criteria and values to apply, my code would
    get messy fast and invite copy & paste errors. Your code is tidy,
    more readable and can be made as short as I wish without loss of
    clarity.

    Many thanks,
    Richard
     
    RichardOnRails, May 28, 2011
    #5
    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. Zeljko

    Template ? Or whatever...

    Zeljko, Nov 21, 2003, in forum: ASP .Net
    Replies:
    3
    Views:
    321
    Saravana [MVP]
    Nov 22, 2003
  2. Scott M.
    Replies:
    2
    Views:
    547
    Kevin Spencer
    Feb 5, 2004
  3. Rob T

    ActiveX, plug-in...whatever

    Rob T, Jan 27, 2005, in forum: ASP .Net
    Replies:
    3
    Views:
    406
    =?Utf-8?B?U293bWk=?=
    Feb 3, 2005
  4. Rico
    Replies:
    3
    Views:
    1,165
    Chris Smith
    Jan 29, 2005
  5. Replies:
    7
    Views:
    454
    Jacek Dziedzic
    Oct 3, 2006
Loading...

Share This Page