anding statements.

Discussion in 'Ruby' started by Kyle Schmitt, May 14, 2008.

  1. Kyle Schmitt

    Kyle Schmitt Guest

    This is odd, I was trying to use "and" to chain together some
    statements, which I thought would work, but it ends up, it doesn't.

    I tried "and", and was surprised that it didn't execute the second
    half of the statement
    I tried "&&" with some extra parenthesis just to see (although I was
    pretty sure and was syntactic sugar for &&), and still no joy.
    I tried "&", and it works with some statements, but not with return statements.
    I know I can do this using a multi-line if, but I'm rather fond of
    single line, sentence like statements.

    I also tried "or", but that makes for slightly nonsensical statement,
    so I'm leaving out that option.
    #This works, but makes a cumbersome statement.
    #puts "#{x} is divisible by two" or return false if x%2==0

    It begs the question, just how does and work, if it doesn't continue
    executing the right half of a statement, even when the left half was
    fine?


    Thanks,
    Kyle


    def something(x)
    puts "#{x} is divisible by two" and return false if x%2==0
    puts "#{x} makes me happy"
    true
    end

    def something_different(x)
    (puts "#{x} is divisible by two")&&(return false) if x%2==0
    puts "#{x} makes me happy"
    true
    end

    def something_that_doesnt_work(x)
    (puts "#{x} is divisible by two")&(return false) if x%2==0
    puts "#{x} makes me happy"
    true
    end

    def something_longer(x)
    if x%2==0
    puts "#{x} is divisible by two"
    return false
    end
    puts "#{x} makes me happy"
    true
    end
     
    Kyle Schmitt, May 14, 2008
    #1
    1. Advertising

  2. Kyle Schmitt

    Kyle Schmitt Guest

    And no, I don't have a strange affinity for odd numbers, it was just
    something to put there.
     
    Kyle Schmitt, May 14, 2008
    #2
    1. Advertising

  3. Consider the following:

    x = 'word'
    z = nil

    test = x && z # test == nil
    test = x and z # test == 'word'
    test = (x and z) # test == nil

    Regards,

    - Mac
    --
    Posted via http://www.ruby-forum.com/.
     
    Michael Linfield, May 14, 2008
    #3
  4. Kyle Schmitt

    Kyle Schmitt Guest

    Mac,
    If your two arguments were methods however, and the first one
    succeeded, wouldn't you expect it to execute the second?

    On Wed, May 14, 2008 at 12:17 PM, Michael Linfield
    <> wrote:
    > Consider the following:
    >
    > x = 'word'
    > z = nil
    >
    > test = x && z # test == nil
    > test = x and z # test == 'word'
    > test = (x and z) # test == nil
    >
    > Regards,
    >
    > - Mac
    > --
    > Posted via http://www.ruby-forum.com/.
    >
    >
     
    Kyle Schmitt, May 14, 2008
    #4
  5. On May 14, 12:28 pm, "Kyle Schmitt" <> wrote:
    > Mac,
    > If your two arguments were methods however, and the first one
    > succeeded, wouldn't you expect it to execute the second?


    The problem is that puts returns nil, which causes the boolean logic
    to short-circuit and not even bother with the second.

    I take that back. *A* problem is that puts returns nil. *The* problem
    is that you're trying to do too much on one line.

    if x % 2 == 0
    puts 'even'
    return false
    end

    It's possible to use 'and' and 'or' and post-condition (statement
    modification) 'if' or 'unless' for clever flow control, but it often
    turns out messier-looking than you think.

    At least you weren't trying something like

    x % 2 == 0 and puts 'even'

    > On Wed, May 14, 2008 at 12:17 PM, Michael Linfield
    >
    > <> wrote:
    > > Consider the following:

    >
    > > x = 'word'
    > > z = nil

    >
    > > test = x && z # test == nil
    > > test = x and z # test == 'word'
    > > test = (x and z) # test == nil

    >
    > > Regards,

    >
    > > - Mac
    > > --
    > > Posted viahttp://www.ruby-forum.com/.


    --
    -yossef
     
    Yossef Mendelssohn, May 14, 2008
    #5
  6. Kyle Schmitt wrote:
    > Mac,
    > If your two arguments were methods however, and the first one
    > succeeded, wouldn't you expect it to execute the second?
    >
    > On Wed, May 14, 2008 at 12:17 PM, Michael Linfield


    Alright I'm going to attempt to explain this without confusing you or
    myself.

    Using '&' is basically comparing. It returns a value if not false.

    1 & 2 #=> 0
    2 & 2 #=> 2

    Using '&&' is self evident.

    "hey" && false
    #=> false

    "hey" && 10
    #=> 10

    true && false
    #=> false

    false && true
    #=> false

    Regards,

    - Mac


    --
    Posted via http://www.ruby-forum.com/.
     
    Michael Linfield, May 14, 2008
    #6
  7. On May 14, 2008, at 1:06 PM, Kyle Schmitt wrote:

    > def something(x)
    > puts "#{x} is divisible by two" and return false if x%2==0
    > puts "#{x} makes me happy"
    > true
    > end


    the problem here is that "puts" returns nil, so the && (and 'and')
    will not reach the next part of the chain, because all of it resolves
    to false:

    >> puts "something"

    something
    => nil
    >> puts("something") && puts("something else")

    something
    => nil
    >> def new_puts(str)
    >> puts(str)
    >> true # this will do the trick
    >> end

    => nil
    >> new_puts("something") && new_puts("something else")

    something
    something else
    => true

    so you either re-def puts or use your own implementation of puts, like
    I did in the example above.
    regards,
    --
    Rolando Abarca M.
     
    Rolando Abarca, May 14, 2008
    #7
  8. Kyle Schmitt

    Todd Benson Guest

    On Wed, May 14, 2008 at 1:04 PM, Michael Linfield
    <> wrote:
    > Kyle Schmitt wrote:
    >> Mac,
    >> If your two arguments were methods however, and the first one
    >> succeeded, wouldn't you expect it to execute the second?
    >>
    >> On Wed, May 14, 2008 at 12:17 PM, Michael Linfield

    >
    > Alright I'm going to attempt to explain this without confusing you or
    > myself.
    >
    > Using '&' is basically comparing. It returns a value if not false.
    >
    > 1 & 2 #=> 0
    > 2 & 2 #=> 2


    No! & is bitwise operator for Fixnum.

    Todd
     
    Todd Benson, May 14, 2008
    #8
  9. On May 14, 2008, at 2:04 PM, Michael Linfield wrote:

    > Kyle Schmitt wrote:
    >> Mac,
    >> If your two arguments were methods however, and the first one
    >> succeeded, wouldn't you expect it to execute the second?
    >>
    >> On Wed, May 14, 2008 at 12:17 PM, Michael Linfield

    >
    > Alright I'm going to attempt to explain this without confusing you or
    > myself.
    >
    > Using '&' is basically comparing. It returns a value if not false.
    >
    > 1 & 2 #=> 0
    > 2 & 2 #=> 2


    AFAIR, '&' is a bitwise and operator:

    1 & 2 -> 0 because 0b01 & 0b10 == 0b00
    2 & 2 -> 2 because 0b10 & 0b10 == 0b10
    1 & 3 -> 1 because 0b01 & 0b11 == 0b01

    no boolean operations are done here.
    regards,
    --
    Rolando Abarca M.
     
    Rolando Abarca, May 14, 2008
    #9
  10. Kyle Schmitt

    Kyle Schmitt Guest

    Dohh! Puts returns nil.

    That explains it. "and" and "&&" work like I expected, but puts doesn't.

    I should have realized & was bitwise and. Interesting how it works
    with nil though.

    I'd rather not redefine puts just to write things in a certain way.


    --Kyle
     
    Kyle Schmitt, May 14, 2008
    #10
  11. Kyle Schmitt

    Adam Shelly Guest

    On 5/14/08, Kyle Schmitt <> wrote:
    >
    > I should have realized & was bitwise and. Interesting how it works
    > with nil though.


    This thread made me look up NilClass in the docs. I learned something new.
    & is a method of nil, which always returns false.
    nil & return(something)
    doesn't work because the & method expects an argument, not a keyword...

    >
    > I'd rather not redefine puts just to write things in a certain way.
    >

    I often do:
    puts "error" or exit if condition
    which reads a little funny, but it works and is concise.
    (I hate reading code where the error handling takes up way more space than
    the essential logic)

    -Adam
     
    Adam Shelly, May 14, 2008
    #11
  12. On 14.05.2008 19:28, Kyle Schmitt wrote:
    > Mac,
    > If your two arguments were methods however, and the first one
    > succeeded, wouldn't you expect it to execute the second?


    No, because "and", "or", "&&" and "||" short circuit - for good reason!
    This allows for safer and more efficient code. Consider

    foo = ... # may be nil

    foo and foo.do_something

    If foo is nil you do not want #do_something to be invoked on it because
    it will raise an exception. Also, it is not worthwhile to invoke it
    because regardless of return value the expression will be false (because
    foo is false).

    Kind regards

    robert
     
    Robert Klemme, May 14, 2008
    #12
    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. Neil Zanella
    Replies:
    8
    Views:
    1,208
    mfmehdi
    Oct 20, 2006
  2. Harry George
    Replies:
    6
    Views:
    417
    Bart Nessux
    Feb 23, 2004
  3. Rahul

    ANDing char and int data items

    Rahul, Mar 14, 2007, in forum: C Programming
    Replies:
    4
    Views:
    372
  4. Vince
    Replies:
    12
    Views:
    762
    Martin Gregorie
    Jan 21, 2008
  5. John Crichton
    Replies:
    6
    Views:
    271
    John Crichton
    Jul 12, 2010
Loading...

Share This Page