Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why aren't these methods resolving?

Tags:

ruby

Given this code:

class Something
  attr_accessor :my_variable

  def initialize
    @my_variable = 0
  end

  def foo
    my_variable = my_variable + 3
  end
end

s = Something.new
s.foo

I get this error:

test.rb:9:in `foo': undefined method `+' for nil:NilClass (NoMethodError)
    from test.rb:14:in `<main>'

If attr_accessor creates a method called my_variable (and ..=), why can't foo find the method? It works if I change it to self.my_variable, but why? Isn't self the default receiver?

like image 503
ryeguy Avatar asked May 30 '11 03:05

ryeguy


People also ask

What methods are used to resolve conflict?

Conflicts can be resolved in a variety of ways, including negotiation, mediation, arbitration, and litigation.

What happens when conflicts are not resolved?

Unresolved conflict can also have a negative impact on the leader-employee relationship. For example, it can result in eroded trust, decreased motivation, lowered morale, increased stress and health risks, decreased performance and productivity, increased absenteeism and presenteeism, and employees quitting.

What is the most effective way of resolving conflict?

Talk it all through Once you start, get all of the issues and feelings out into the open. Don't leave out the part that seems too "difficult" to discuss or too "insignificant" to be important. Your solutions will work best if all issues are discussed thoroughly.

Why is it important to resolve conflict?

Conflict resolution can help bring people together once an issue is put to rest. One of the most important elements in conflict resolution is choosing to tackle problems as a team, rather than attacking each other.


1 Answers

You're not calling the method there, you're actually referencing the same variable you're in the process of defining! This is a little gotcha in Ruby.

What would be better is if you referenced and set the instance variable instead:

@my_variable = @my_variable + 3

Or shorter:

@my_variable += 3

Or you could call the setter method, as you found (and Jits pointed) out:

self.my_variable += 3

This last one will call the my_variable= method defined by the attr_accessor, where the other two will only modify a variable. If you did it this way, you could override my_variable= to do something different to the value passed in:

def my_variable=(value)
  # do something here
  @my_variable = value
end

BONUS

Or you could call the method explicitly by passing an empty set of arguments through:

my_variable = my_variable() + 3

This is not "The Ruby Way" to go about it, but it's still interesting to know that you can still call a method this way if you have a local variable of the same name.

like image 147
Ryan Bigg Avatar answered Sep 22 '22 23:09

Ryan Bigg