Self. vs. @

I’m working on an application that creates a confirmation e.mail
whenever you create and account or change an e.mail address. I
thought I’d just use the same key generation code used for the
password hash login example from the Agile Rails book.

The function to create a salt value keeps failing complaining I have a
nil object where I don’t expect it.

The code where it breaks is:

def create_new_salt
self.salt = @user_id.to_s + rand.to_s
end

I’ve also put a constant string assigned to self.salt, but the error
still occurs, as if self.salt points to a nil object, but I don’t see
how that can happen. I also don’t understand any reason for this
function to call self.salt, instead of @salt. Any clues would be much
appreciated.

Thanks,
j

PS here is the table definition for this model.

:created_at, :timestamp
:email, :string
:type, :string #which of several e.mail columns in ‘user’ does this
change apply to
:user_id, integer
:key, :string #randomly generated key
:salt, :string

That code seems to be fine. Look at where create_new_salt is being
called, it’s probably being called on a nil Object instead of an AR
model, possible a find condition returning nil instead of the
model(s).

Vish

Thanks for your help. create_new_salt is only ever called from within
the the model object. Here is the only function that calls it:

def initialize(id, address, type)
@email = address
@type = type
@user_id = id
create_new_salt
self.key = self.encrypt_key(self.email, self.salt)
end

Perhaps I can’t call it until after initialize has run? Also I still
don’t understand why I should call self.salt in some of these cases
and not @salt.

Thanks,
j

Thanks for the info. I do realize that one is a function and the
other is the member.

What I’m still unclear on is why in an ActiveRecord derived object one
would choose to use one over the other. If there is logic happening
with the self.name assignment, then why would we not always call
self.name in ActiveRecord objects as a rule, however that doesn’t seem
to be the case. In the book examples several members were assigned as
@some_data = something, while this salt value was set with
self.salt.

Thanks,
j

Joshua K. wrote:

how that can happen. I also don’t understand any reason for this
function to call self.salt, instead of @salt. Any clues would be
much
appreciated.

I don’t know much about the book example you refer to but you seem to
have some confusion between “self.salt = foo” and “@salt = foo”

When you do “@salt = foo” it is simply making the instance variable
“salt” point to whatever “foo” is pointing at. If you do “self.salt =
foo” then you are calling the method “salt=” with the argument “foo”.
The method “salt=” could do anything. One might think it is typically
defined as:

def salt=(val)
@salt = val
end

but it could be defined as

def salt=(val)
@salt = rand
end

Sounds like you need to see how “salt=” is defined. Until then you won’t
know why it is not working.

Eric

Well, there you have it, you can’t easily override initialize for AR
objects. It shouldn’t work alright with create_new_salt being removed
from there too.

See this:
http://blog.hasmanythrough.com/2007/1/22/using-faux-accessors-to-initialize-values

What you’re trying to do can possibly be done like this:

Model.new(:email => address, :type => type, :user = user) and an
after_initialize callback.

Also, usually, @salt = and self.salt = are the same thing inside a
model. salt= is a function equivalent to this:

def salt=(var)
@salt = var
end

(it’s part of an attr_accessor definition.) If you didn’t have the
accessor tho, you wouldn’t be able to call it from outside the model
since instance variables are private.

Vish

Joshua K. wrote:

What I’m still unclear on is why in an ActiveRecord derived object one
would choose to use one over the other. If there is logic happening
with the self.name assignment, then why would we not always call
self.name in ActiveRecord objects as a rule, however that doesn’t seem
to be the case. In the book examples several members were assigned as
@some_data = something, while this salt value was set with
self.salt.

I in general always use the function version. That way if there is
custom logic it will run. If there is not then it will work just like
assigning a instance variable. I guess to me the function encapsulates
better.

Eric

On Aug 13, 12:40 pm, “Vishnu G.” [email protected] wrote:

Well, there you have it, you can’t easily override initialize for AR
objects. It shouldn’t work alright with create_new_salt being removed
from there too.

See this:http://blog.hasmanythrough.com/2007/1/22/using-faux-accessors-to-init

Great thanks, that’s my issue. I’m still not clear on why various
examples (including the book) switch between @member, and self.member,
but just changing this to a different function then initialize has
gotten me past the nil error.

Thanks!
j