Error when using class variables with operators

Hi. When I use class variables with operators I get the following error
message…

undefined method `>’ for nil:NilClass

here’s a piece of code that gives this error…

if @@target1 < @@target2
@@status = true

On Wednesday 06 October 2010, Paul R. wrote:

|Hi. When I use class variables with operators I get the following error
|message…
|
| undefined method `>’ for nil:NilClass
|
|
|here’s a piece of code that gives this error…
|
|if @@target1 < @@target2
| @@status = true

It means that @@target1 is nil. Try

p @@target1

just before the if and see what it shows.

Stefano

Stefano C. wrote:

On Wednesday 06 October 2010, Paul R. wrote:

|Hi. When I use class variables with operators I get the following error
|message…
|
| undefined method `>’ for nil:NilClass
|
|
|here’s a piece of code that gives this error…
|
|if @@target1 < @@target2
| @@status = true

It means that @@target1 is nil. Try

p @@target1

just before the if and see what it shows.

Stefano

The problem is I intialise the attributes first…

def initialize(tar1, tar2)
@@target1 = tar1
@@target2 = tar2
end

Then I use this method…

def self.on_target?(mltn)
mltn.each do |trg|
if trg.target1 > trg.target2
then p “on target”
else
off_target
end
end
end

and call this method in the method above…

def off_target
@@target1 = @@target1 - @@target2
end

So I want to make off_target accessable which is why I use @@

On Wednesday 06 October 2010, Paul R. wrote:

|>> |
|The problem is I intialise the attributes first…
|mltn.each do |trg|
|def off_target
|@@target1 = @@target1 - @@target2
|end
|
|So I want to make off_target accessable which is why I use @@

I truly can’t understand how your code should work. However, here are
some
remarks:

  1. have you tried following my suggestion and displaying the content of
    the
    class variables before trying the comparison? If so, are you they’re not
    nil?
  2. In the code you posted in your second message, there’s no comparison
    between class variables.
  3. It generally makes little sense to initialize class variables from
    the
    initialize method. This way, every time you create an instance of your
    class,
    the class variables are set to new values. There may be situations where
    this
    is the correct behaviour, but I think they’re quite rare. Usually, in
    this
    case, instance variables are the correct choice
  4. You call the off_target instance method from the on_target class
    method.
    This can’t work. Either you made a mistake while writing your mail
    (meaning
    that both method are class methods or both are instance methods) or your
    code
    will fail as soon as has to execute the else clause, because off_target
    can
    only be called on an instance of your class, while in the body of the
    on_target? method, the implicit receiver, that is, self, is the class
    itself.

Stefano

On 10/6/2010 2:01 PM, Paul R. wrote:

|if @@target1 < @@target2
The problem is I intialise the attributes first…
mltn.each do |trg|
def off_target
@@target1 = @@target1 - @@target2
end

So I want to make off_target accessable which is why I use @@

You don’t need @@ in order to make off_target accessible. That method
is already accessible from any instance of your class. What you
probably mean is that you need @@ to make target1 and target2
accessible. However, the @@target1 and @@target2 variables are actually
class variables shared among all instances of your class, which is
probably not what you want.

class MyClass
def initialize(value)
@@value = value
end

def get_value
@@value
end
end

my_class1 = MyClass.new(1)
my_class1.get_value # => 1

my_class2 = MyClass.new(“unexpected”)

my_class1.get_value # => “unexpected”

What you want instead are instance variables such as @target1 and
@target2. I found these notations a little hard to remember at first,
but you’ll find that defining class variables is pretty rare and that
you can usually just use @variable. :slight_smile:

-Jeremy

On 10/6/2010 2:58 PM, Jeremy B. wrote:

|

def self.on_target?(mltn)

class variables shared among all instances of your class, which is
end
@target2. I found these notations a little hard to remember at first,
but you’ll find that defining class variables is pretty rare and that
you can usually just use @variable. :slight_smile:

Hmm. Looking closer at what you’re trying to do, I see that you do need
the class variables in your current implementation. The problem is that
I can’t figure out why you are trying to use a class method (on_target?)
for this rather than an instance method. It looks like Stefano is also
confused about what you’re trying to do here.

Please understand that you are mixing together class and instance
methods. For now you should probably stick to instance methods since
they are more common:

class MyClass
def my_instance_method

end
end

Rather than…

class MyClass
def self.my_class_method

end
end

Once you have a handle on instance methods, understanding class methods
and how they differ from instance methods will be easier.

-Jeremy

Jeremy B. wrote:

On 10/6/2010 2:58 PM, Jeremy B. wrote:

|

def self.on_target?(mltn)

class variables shared among all instances of your class, which is
end
@target2. I found these notations a little hard to remember at first,
but you’ll find that defining class variables is pretty rare and that
you can usually just use @variable. :slight_smile:

Hmm. Looking closer at what you’re trying to do, I see that you do need
the class variables in your current implementation. The problem is that
I can’t figure out why you are trying to use a class method (on_target?)
for this rather than an instance method. It looks like Stefano is also
confused about what you’re trying to do here.

Please understand that you are mixing together class and instance
methods. For now you should probably stick to instance methods since
they are more common:

class MyClass
def my_instance_method

end
end

Rather than…

class MyClass
def self.my_class_method

end
end

Once you have a handle on instance methods, understanding class methods
and how they differ from instance methods will be easier.

-Jeremy

Thanks guys for the help. Stefano, I stuck a ‘p’ in and I got a nil.
Jeremy I understand where you are coming from when you say stick to
instance methods before using class methods. However I need to make one
method a class method (it’s more complex than the example I gave above).
I will then be calling a method from here (presumingly this has to be a
class method too?) Thanks for the patience, I’m slow on the uptake