Why is my var undefined?

Discussion in 'Ruby' started by Tim, Feb 3, 2008.

  1. Tim

    Tim Guest

    I'm new to ruby and I have the following code:

    index=0
    unsorted_array.each do |value|
    if index==0
    smallest=value
    smallest_index=0
    elsif value<smallest
    smallest=value
    smallest_index=index
    end
    index=index+1
    end

    When it gets to index 1, it crashes and says that smallest is
    undefined (on the elsif line). Why is that, when it gets defined in
    the first pass (index = 0) ?

    Thanks for helping a newbie out.

    Tim
     
    Tim, Feb 3, 2008
    #1
    1. Advertising

  2. Tim

    Ilan Berci Guest

    Tim wrote:
    > I'm new to ruby and I have the following code:
    >
    > index=0
    > unsorted_array.each do |value|
    > if index==0
    > smallest=value
    > smallest_index=0
    > elsif value<smallest
    > smallest=value
    > smallest_index=index
    > end
    > index=index+1
    > end
    >
    > When it gets to index 1, it crashes and says that smallest is
    > undefined (on the elsif line). Why is that, when it gets defined in
    > the first pass (index = 0) ?
    >
    > Thanks for helping a newbie out.
    >
    > Tim


    It's only defined for the scope that it's in.. which is the "if" block..
    Once it leaves that block and your code returns to the
    "unsorted_array.each" scope, "smallest" is out of scope and therefore no
    longer defined.

    Dave Thomas has a free online version of Ruby 1.6 referred as the Pick
    Axe book which discusses scope and I think you will find it very useful

    hth

    ilan

    --
    Posted via http://www.ruby-forum.com/.
     
    Ilan Berci, Feb 3, 2008
    #2
    1. Advertising

  3. Tim

    Todd Benson Guest

    On Feb 2, 2008 6:09 PM, Tim <> wrote:
    > I'm new to ruby and I have the following code:
    >
    > index=0


    you could insert "smallest = nil" here

    > unsorted_array.each do |value|
    > if index==0
    > smallest=value
    > smallest_index=0
    > elsif value<smallest
    > smallest=value
    > smallest_index=index
    > end
    > index=index+1
    > end
    >
    > When it gets to index 1, it crashes and says that smallest is
    > undefined (on the elsif line). Why is that, when it gets defined in
    > the first pass (index = 0) ?


    Not sure what you are trying to do, but if your data is not unique...

    a = 5,1,4,7,2,1,9,2,1
    smallest = a.min
    s_indexes = []
    a.each_with_index {|v, i| s_indexes << i if v == a.min}

    If you don't want to do it that way, then...

    a = 5,1,4,7,2,1,9,2,1
    smallest, s_indexes = a.first, []
    a.inject(a.first) {|m, e| e < m ? e : m}
    a.each_with_index {|v, i| s_indexes << i if v == a.min}

    Todd
     
    Todd Benson, Feb 3, 2008
    #3
  4. Tim

    Todd Benson Guest

    On Feb 2, 2008 11:05 PM, Todd Benson <> wrote:
    > a.inject(a.first) {|m, e| e < m ? e : m}
    > a.each_with_index {|v, i| s_indexes << i if v == a.min}



    Sorry, these lines are supposed to be...

    smallest = a.inject(a.first) {|m, e| e < m ? e : m}
    a.each_with_index {|v, i| s_indexes << i if v <= smallest}

    Todd
     
    Todd Benson, Feb 3, 2008
    #4
  5. Tim

    Isidor Isa Guest

    Todd Benson wrote:
    > On Feb 2, 2008 11:05 PM, Todd Benson <> wrote:
    >> a.inject(a.first) {|m, e| e < m ? e : m}
    >> a.each_with_index {|v, i| s_indexes << i if v == a.min}

    >
    >
    > Sorry, these lines are supposed to be...
    >
    > smallest = a.inject(a.first) {|m, e| e < m ? e : m}
    > a.each_with_index {|v, i| s_indexes << i if v <= smallest}
    >
    > Todd


    In Ruby 1.9, finding indexes of all elements which have minimal value
    is easily done using a new iterator chaining feature:



    a = 5, 1, 4, 7, 2, 1, 9, 2, 1

    min_value = a.min



    a.each_with_index.inject([]){|accum, (elem, index)|

    elem == min_value ? accum << index : accum

    }

    Output:

    => [1, 5, 8]


    Best regards
    Isidor Nikolic
    --
    Posted via http://www.ruby-forum.com/.
     
    Isidor Isa, Feb 3, 2008
    #5
  6. On Feb 3, 2008 1:09 AM, Tim <> wrote:
    > I'm new to ruby and I have the following code:
    >


    Add
    smallest = nil
    smallest_index = 0
    here, and your code will work.


    > index=0
    > unsorted_array.each do |value|
    > if index==0
    > smallest=value
    > smallest_index=0
    > elsif value<smallest
    > smallest=value
    > smallest_index=index
    > end
    > index=index+1
    > end
    >
    > When it gets to index 1, it crashes and says that smallest is
    > undefined (on the elsif line). Why is that, when it gets defined in
    > the first pass (index = 0) ?


    The variable is not "pass"-based - it is "scope" based, ie, it only
    exists inside a particular *lexical* - that is, textual - part of your
    program (in this case, your if statement, NOT the loop). In other
    words, you get a new variable for each pass through the loop.

    By adding the initialization, you get th same variable all loop iterations.

    Here is another variant of your code that uses essensially the same
    algorithm and simplifies the code a bit:

    smallest_index = 0
    smallest_value = nil
    unsorted_array.each_with_index do |value, index|
    if !smallest_value || value<smallest
    smallest=value
    smallest_index=index
    end
    end


    Eivind.
     
    Eivind Eklund, Feb 3, 2008
    #6
  7. Ilan Berci wrote:
    > It's only defined for the scope that it's in.. which is the "if" block


    It's not local to the if-block. It's local to each execution of the each-
    block.

    HTH,
    Sebastian
    --
    NP: Shape of Despair - Angels of Distress
    Jabber:
    ICQ: 205544826
     
    Sebastian Hungerecker, Feb 3, 2008
    #7
  8. On Feb 3, 2008 11:50 AM, Eivind Eklund <> wrote:
    > The variable is not "pass"-based - it is "scope" based, ie, it only
    > exists inside a particular *lexical* - that is, textual - part of your
    > program (in this case, your if statement, NOT the loop).


    This was slightly clumsily written; the variable leak through to the
    end of the block, but isn't present for the entire loop. Sebastians
    description is correct.

    Eivind.
     
    Eivind Eklund, Feb 3, 2008
    #8
  9. Tim

    Tim Guest

    Thanks to all for the help. I take it from the comments here that any
    variables which are defined in an iteration block (or a Proc)are local
    to each iteration. Thinking about it, that makes sense because each
    iteration requires its own call from each (or each_with_index,
    etc.)...with the variables being treated somewhat like method
    variables.
     
    Tim, Feb 3, 2008
    #9
    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. Alvin Bruney

    Threads.. Session var lost, App var ok

    Alvin Bruney, Dec 2, 2003, in forum: ASP .Net
    Replies:
    1
    Views:
    385
    rooster575
    Dec 2, 2003
  2. thomson
    Replies:
    10
    Views:
    2,531
    Eliyahu Goldin
    Jun 20, 2005
  3. thomson
    Replies:
    0
    Views:
    406
    thomson
    Jun 20, 2005
  4. Fred
    Replies:
    3
    Views:
    342
    Alf P. Steinbach
    Aug 10, 2003
  5. Mr. SweatyFinger
    Replies:
    2
    Views:
    2,253
    Smokey Grindel
    Dec 2, 2006
Loading...

Share This Page