Rails -- Self VS. @

Instance variable: self vs @

Writing @age directly accesses the instance variable @age. Writing self.age tells the object to send itself the message age, which will usually return the instance variable @age — but could do any number of other things depending on how the age method is implemented in a given subclass. For example, you might have a MiddleAgedSocialite class that always reports its age 10 years younger than it actually is. Or more practically, a PersistentPerson class might lazily read that data from a persistent store, cache all its persistent data in a hash.

ruby should I use self. or @

When you use @lines, you are accessing the instance variable itself. self.lines actually goes through the lines method of the class; likewise, self.lines = x goes through the lines= method. So use @ when you want to access the variable directly, and self. when you want to access via the method.

To directly answer your question, normally you want to set the instance variables directly in your initialize method, but it depends on your use-case.

Rails -- self vs. @

The accessors for encrypted_password have been automatically added by Rails for you because a field by that name exists in the users table.

Any field you add to a table will be automatically made available via self.field_name.

Here is where Michael Hartl's tutorial creates the encrypted_password field in the users table.

Also look at the user_spec.rb (Listing 7.3) in the linked page, where the author is testing for the presence of the encrypted_password field.

UPDATED:

As @mu points out, the @ is used for Ruby instance variables (aka "iv"). But encrypted_password is an "attribute" defined by Rails, and is not an instance variable.

If you run User.find(1).instance_variables, you will see that there is an iv called @attributes, which is of type Hash.

Inside that iv is where the encrypted_password is stored. Rails has defined accessor methods for encrypted_password, which gets/sets the data for that
attribute in the @attributes Hash.

Note that you could also get/set the data via @attributes["encrypted_password"] called from within the User class (but the accessor methods are convenient way to do just that).

class self vs self.method with Ruby: what's better?

class << self is good at keeping all of your class methods in the same block. If methods are being added in def self.method form then there's no guarantee (other than convention and wishful thinking) that there won't be an extra class method tucked away later in the file.

def self.method is good at explicitly stating that a method is a class method, whereas with class << self you have to go and find the container yourself.

Which of these is more important to you is a subjective decision, and also depends on things like how many other people are working on the code and what their preferences are.

What's the difference between using self.attribute and attribute in a model?

The difference in your examples is that the first one works, the second doesn't.

Your second version isn't doing anything (at least nothing meaningful). Writing my_attr = 123 is not equivalent to self.my_attr = 123. Instead it's creating a local variable called my_attr and setting it to 123, and then immediately reaching the end of the method and throwing my_attr away. The whole method is essentially a no-op, and it doesn't affect the model's my_attr value in any way.

class User < ActiveRecord::Base
def do_another_thing!
my_attr = 456

puts self.my_attr # nil (or whatever value it was before)
end
end

Conversely, if you want to access a method defined on an object, you can (and should) omit self:

class User
def name=(value)
@name = value
end

def name
@name
end

def age=(value)
@age = value
end

def age
@age
end

def do_something
self.name = "bob" # self is required
puts name # bob (self.name)

age = 47 # @age is unaffected
age # 47 (local variable), but self.age is nil

end
end

Note that, this isn't a Rails question, it's a Ruby question. There is no Rails-specific code here, this behaviour is part of how Ruby's syntax works.

Ruby self. vs @ in initialize

They are the same thing.

self.username = calls the username= function which is defined by attr_accessor. That function looks like this:

def username=(value)
@username = value
end

As you can see, it is identical to the "alternative" you mentioned.

EDIT Using an accessor (i.e. calling the function defined by attr_accessor/reader/etc) is significantly faster than other forms of access. There are a few links in the comments which elaborate more on this.

Rails: difference between self.function and self.class.function

def self.function2 is your class method that can not be called with instance of class. It call like TestClass.function2. While def function3 is instance method. You are calling it right.

myvar = TestClass.new
myvar.function3

So if we follow flow. Under function3 self will become instance that is calling that function.

var3 = self.class.function2 # Here self is myvar
# self.class == TestClass
# self.class.function2 == TestClass.function2 # No error
# self.function2 == myvar.function2 # error, Calling class method with instance of class.

Now if you try to call class method with instance it will surely through error.

Rails Model method self. vs plain

self.method_name indicates a class method; method_name indicates an instance method.

You can read a lot more about class and instance methods at this blog post or, if you'd prefer something a bit more official, the Programming Ruby class section.

Rails, activerecord: self[:attribute] vs self.attribute

They're both just methods to get to the attribute - they're both just getters. self.attribtue is a more "traditional" getter, whereas self[:attribute] is basically just the [] method. Switching between using either has no ramifications.

I'd recommend using only the self.attribute method because it's syntactically nicer. However, using the self[:attribute] can come in handy when something else overrides the self.attribute method.

For example, suppose you have a User model with a name database column, so you'd get user.name. But let's say you install a gem that adds a #name method to each of your models. To avoid the complication, one option is to use user[:name] to access it directly without going through the compromised method.



Related Topics



Leave a reply



Submit