Modules setting values to nil in unprocessed conditional blocks?

Discussion in 'Ruby' started by Nate, Aug 24, 2009.

  1. Nate

    Nate Guest

    Hi everyone. We're noticing some strange behavior when including
    modules in classes. It seems that even if a conditional block is
    forced to evaluate as false (and presumably not execute), assignments
    in the conditional block are executed and set to nil. Here is an
    example:

    ==========================
    module Conundrum
    def riddle
    @riddle ||= 'mystery'
    end

    def riddle=(new_val)
    puts "Called riddle="
    @riddle = new_val
    end
    end

    class Test
    include Conundrum

    def test
    puts "Before: #{riddle}"
    if true == false
    riddle = 'solved!'
    end
    puts "After: #{riddle}"
    puts "After class: #{riddle.class}"
    end
    end

    Test.new.test
    ==========================

    Note that this prints out:

    Before: mystery
    After:
    After class: NilClass

    So it would seem that riddle= is not getting called, but yet the
    riddle function now returns nil. Interestingly, this fixes the
    problem:

    ==========================
    module Conundrum
    def riddle
    @riddle ||= 'mystery'
    end

    def riddle=(new_val)
    puts "Called riddle="
    @riddle = new_val
    end
    end

    class Test
    include Conundrum

    def test
    puts "Before: #{riddle}"
    if true == false
    @riddle = 'solved!'
    end
    puts "After: #{riddle}"
    puts "After class: #{riddle.class}"
    end
    end

    Test.new.test
    ==========================

    Outputs:

    Before: mystery
    After: mystery
    After class: String

    Any insights are much appreciated!

    -n8
     
    Nate, Aug 24, 2009
    #1
    1. Advertising

  2. Nate

    7stud -- Guest

    Re: Modules setting values to nil in unprocessed conditional

    Nate wrote:
    > Hi everyone. We're noticing some strange behavior when including
    > modules in classes. It seems that even if a conditional block is
    > forced to evaluate as false (and presumably not execute), assignments
    > in the conditional block are executed and set to nil. Here is an
    > example:
    >
    > ==========================
    > module Conundrum
    > def riddle
    > @riddle ||= 'mystery'
    > end
    >
    > def riddle=(new_val)
    > puts "Called riddle="
    > @riddle = new_val
    > end
    > end
    >
    > class Test
    > include Conundrum
    >
    > def test
    > puts "Before: #{riddle}"
    > if true == false



    Inside test, self is equal to the Test instance you created here:

    > Test.new.test


    And this line:

    > puts "Before: #{riddle}"


    is equivalent to:

    > puts "Before: #{self.riddle}"


    However, when ruby parses this line:

    > riddle = 'solved!'


    ruby creates a local variable named riddle. As a result, when you get
    to this statement:

    > puts "After: #{riddle}"


    riddle is no longer equivalent to self.riddle. Instead riddle is just
    riddle; and riddle is a local variable that hasn't been assigned a
    value. For local variables that exist but have not been assigned a
    value, ruby returns nil for the value of the variable. Then the string
    interpolation calls nil.to_s which returns a blank string.

    --
    Posted via http://www.ruby-forum.com/.
     
    7stud --, Aug 24, 2009
    #2
    1. Advertising

  3. Nate

    7stud -- Guest

    Re: Modules setting values to nil in unprocessed conditional

    7stud -- wrote:
    >
    > However, when ruby parses this line:
    >
    >> riddle = 'solved!'

    >
    > ruby creates a local variable named riddle.


    Just to clarify: "parse" is different than "execute". That line will
    never execute, but ruby still parses the code; and it's when ruby parses
    the code that the local variable riddle is created.
    --
    Posted via http://www.ruby-forum.com/.
     
    7stud --, Aug 24, 2009
    #3
  4. Nate

    n8agrin Guest

    Re: Modules setting values to nil in unprocessed conditional

    On Aug 24, 9:14 am, 7stud -- <> wrote:
    > 7stud -- wrote:
    >
    > > However, when ruby parses this line:

    >
    > >>       riddle = 'solved!'

    >
    > > ruby creates a local variable named riddle.  

    >
    > Just to clarify: "parse" is different than "execute".  That line will
    > never execute, but ruby still parses the code; and it's when ruby parses
    > the code that the local variable riddle is created.
    > --
    > Posted viahttp://www.ruby-forum.com/.


    Clicked "Reply to Author" accidently earlier but meant to give some
    public thanks for your response. So, thanks, appreciate the response
    and the precision you provided in your answer.

    - n8 -
     
    n8agrin, Aug 24, 2009
    #4
    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. matt
    Replies:
    1
    Views:
    270
    George Ogata
    Aug 6, 2004
  2. Brian Candler

    puts nil generates "nil\n"

    Brian Candler, Nov 6, 2004, in forum: Ruby
    Replies:
    1
    Views:
    113
  3. John Carter
    Replies:
    64
    Views:
    647
    Klaus Stein
    May 19, 2005
  4. ako...

    a == nil or a.nil?

    ako..., Nov 22, 2005, in forum: Ruby
    Replies:
    6
    Views:
    145
    Douglas Livingstone
    Nov 23, 2005
  5. Christoffer Sawicki
    Replies:
    5
    Views:
    261
    Christoffer Sawicki
    Sep 2, 2006
Loading...

Share This Page