# Newb confusion: instance variable accessible from outside class, but nil from inside instance metho

**URL:** <https://www.ruby-forum.com/t/newb-confusion-instance-variable-accessible-from-outside-class-but-nil-from-inside-instance-metho/153640>\
**Category:** Rails\
**Created:** [November 19, 2008, 5:49pm UTC](https://www.ruby-forum.com/t/newb-confusion-instance-variable-accessible-from-outside-class-but-nil-from-inside-instance-metho/153640 "2008-11-19T17:49:49Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![brian](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/97f17d/32.png) [@brian](https://www.ruby-forum.com/u/brian)\
**Post date:** [November 19, 2008, 5:49pm UTC](https://www.ruby-forum.com/t/newb-confusion-instance-variable-accessible-from-outside-class-but-nil-from-inside-instance-metho/153640/1 "2008-11-19T17:49:49Z")

</div>

I’ve got a simple class, defined by the following table in a  
migration:

create\_table :buzzusers do |t|  
t.integer :user\_id  
t.string :name  
t.integer :level, :default =\> 0

t.timestamps  
end

I usually create it with the following

Buzzuser.create(:name =\> “Bob”)

which works fine. It appears to save and load fine. I’ve written the  
following method within the Buzzuser class model:

def promote  
@level += 1  
end

This blows up with a nil error when called. More precisely, I get:

NoMethodError: You have a nil object when you didn’t expect it!  
You might have expected an instance of Array.  
The error occurred while evaluating nil.+

However, if I’m outside the class, I can access the level variable  
just fine. If I do

bu = Buzzuser.find(1)

I can then do bu.level and it returns the correct value for level.

What’s wrong? I’m assuming I’m missing something basic, but it’s  
pretty confusing.

Thanks

---

<div class="post-metadata">

**Author:** ![brian](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/97f17d/32.png) [@brian](https://www.ruby-forum.com/u/brian)\
**Post date:** [November 19, 2008, 5:56pm UTC](https://www.ruby-forum.com/t/newb-confusion-instance-variable-accessible-from-outside-class-but-nil-from-inside-instance-metho/153640/2 "2008-11-19T17:56:52Z")

</div>

On 19 Nov 2008, at 16:48, Brian wrote:

> What’s wrong? I’m assuming I’m missing something basic, but it’s  
> pretty confusing.

attributes aren’t instance variables

Fred

---

<div class="post-metadata">

**Author:** ![brian](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/97f17d/32.png) [@brian](https://www.ruby-forum.com/u/brian)\
**Post date:** [November 19, 2008, 7:20pm UTC](https://www.ruby-forum.com/t/newb-confusion-instance-variable-accessible-from-outside-class-but-nil-from-inside-instance-metho/153640/3 "2008-11-19T19:20:18Z")

</div>

thanks for the response, but can anyone provide a simple example of  
the proper way to access and change an attribute from within an  
instance method?

I’ve worked through AWDwR, re-read the ActiveRecord and Ruby sections,  
am currently going through [wiki.rubyonrails.org](http://wiki.rubyonrails.org) and the Reference  
Docs, and still haven’t found it.

On Nov 19, 11:55 am, Frederick C. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

---

<div class="post-metadata">

**Author:** ![brian](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/97f17d/32.png) [@brian](https://www.ruby-forum.com/u/brian)\
**Post date:** [November 19, 2008, 8:06pm UTC](https://www.ruby-forum.com/t/newb-confusion-instance-variable-accessible-from-outside-class-but-nil-from-inside-instance-metho/153640/4 "2008-11-19T20:06:22Z")

</div>

On Nov 19, 6:19 pm, Brian [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> thanks for the response, but can anyone provide a simple example of  
> the proper way to access and change an attribute from within an  
> instance method?

You just need to call the accessor methods, same as for people outside  
the class. the only subtlety is that to set it you need to do  
self.attribute\_name = value (as attribute\_name = value would be  
interpreted as you trying to set a local variable)

Fred

---

<div class="post-metadata">

**Author:** ![brian](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/97f17d/32.png) [@brian](https://www.ruby-forum.com/u/brian)\
**Post date:** [November 19, 2008, 8:49pm UTC](https://www.ruby-forum.com/t/newb-confusion-instance-variable-accessible-from-outside-class-but-nil-from-inside-instance-metho/153640/5 "2008-11-19T20:49:21Z")

</div>

ok thanks that got it working. I think I had this working before like  
that, but then changed it because of confusion over the usage of  
self. I thought self was used to define class-level methods.  
Apparently the usage is different in instance methods? It is partly  
addressed here

[http://wiki.rubyonrails.org/rails/pages/RubyHeadScratching](http://wiki.rubyonrails.org/rails/pages/RubyHeadScratching)

On Nov 19, 1:56 pm, Frederick C. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

---

<div class="post-metadata">

**Author:** ![brian](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/97f17d/32.png) [@brian](https://www.ruby-forum.com/u/brian)\
**Post date:** [November 19, 2008, 9:06pm UTC](https://www.ruby-forum.com/t/newb-confusion-instance-variable-accessible-from-outside-class-but-nil-from-inside-instance-metho/153640/6 "2008-11-19T21:06:23Z")

</div>

On Nov 19, 7:49 pm, Brian [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> ok thanks that got it working. I think I had this working before like  
> that, but then changed it because of confusion over the usage of  
> self. I thought self was used to define class-level methods.  
> Apparently the usage is different in instance methods? It is partly  
> addressed here

Self is simple when you get it right. It just means ‘the current  
object’. The only reason it is relevant here is that when ruby sees  
self.foo = bar it can be damn sure you want to call the method foo= on  
the current object, whereas with foo= bar you might just want to  
create a local variable.

in the same way  
def self.foo  
end

creates a class method (in the context of a class) because it says  
“define a method on the object self” (as opposed to inside the  
appropriate class), given that at this point the self object is the  
class, this creates a method on that class object.

so for example

class Foo  
def self.bar  
puts “hi”  
end  
end

is the same as  
class Foo  
def Foo.bar  
puts “hi”  
end  
end

is the same (from the point of view of method definition - constant  
scopes and so on would be different) as

class Foo  
end

def Foo.bar  
puts “hi”  
end

In the first example self is at that point Foo, which is why it works.  
It’s more convenient that typing Foo.bar partly because class names  
are usually longer, partly because it stands out more and partly  
because if you were to rename the Foo class you can leave all of your  
def self.bar alone whereas with the second example you would have to  
change def Foo.bar to def NewClassName.bar

Fred
