Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setting attribute from model without using self doesn't work

Device model has following attributes: name, version and full_name

Full name is name + version:

class Device < ActiveRecord::Base
  def prepare
    full_name = (!show_version || version.nil?)? name : name + " " + version.to_s
  end
end

When i do following:

d = Device.new :name => "iPhone", :version => "4"
d.prepare
d.full_name # get nil

I get nil for "full_name" attribute

When I'm using "self", it works:

class Device < ActiveRecord::Base
  def prepare
    self.full_name = (!show_version || version.nil?)? name : name + " " + version.to_s
  end
end

Doing "prepare" i get "iPhone 4" for "full_name" attribute.

Some people here told me, that it's a good manner to avoid using "self" inside class methods. But this brings trouble.

The question is - why it does't works without using "self" ?

like image 615
AntonAL Avatar asked Nov 28 '22 18:11

AntonAL


2 Answers

In these cases you have to use self, I don't think it's a trouble. If you are using self then the interpreter will know that you refer to the object's attribute. If you don't use self it means that it's just an local variable which is not stored anywhere after the method finishes.That's the normal behavior. You can also use self[:full_name]= ... as a setter method, but in this case doesn't really matter.

Update

@AntonAL

Because the getter methods are recognized without the self..

When you try to use the name attribute, the interpreter will look for a local variable within the current method. If doesn't finds then looks for an instance attribute. Example:

def your_method
  self.name = 'iPhone'
  puts name
  #iPhone
  name = 'iPod'
  puts name
  #iPod
  puts self.name
  #iPhone
end

And iPhone will be stored in your object instance's name attribute. And iPod will be lost after the method finishes.

like image 85
dombesz Avatar answered Dec 10 '22 05:12

dombesz


When you use setters, you need to use self because otherwise Ruby will interpret it as a new local variable full_name being defined.

For getters, we dont need to call self because Ruby first search for a local variable full_name and when it does not have a local variable full_name, it will search for a method full_name and will get the getter. If you have a local variable defined full_name, it will return the value of local variable.

This is explained better in a previous question

like image 35
rubyprince Avatar answered Dec 10 '22 04:12

rubyprince