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

···

--
Posted via http://www.ruby-forum.com/.

It means that @@target1 is nil. Try

  p @@target1

just before the if and see what it shows.

Stefano

···

On Wednesday 06 October 2010, Paul Roche 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

Stefano Crocco 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 Roche wrote:

--
Posted via http://www.ruby-forum.com/\.

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:01 PM, Paul Roche wrote:

Stefano Crocco wrote:

On Wednesday 06 October 2010, Paul Roche 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 @@

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 Wednesday 06 October 2010, Paul Roche wrote:

>Stefano Crocco wrote:
>> On Wednesday 06 October 2010, Paul Roche 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 @@

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

···

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

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

Stefano Crocco wrote:

On Wednesday 06 October 2010, Paul Roche 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 @@

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 Bopp wrote:

···

On 10/6/2010 2:58 PM, Jeremy Bopp 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
--
Posted via http://www.ruby-forum.com/\.