Reputation: 128357
I almost never see this in Ruby code, but it seems to be valid:
class Foo
@bar = "bar"
def self.print_bar
puts @bar
end
end
My interpretation of the above that @bar
is an instance variable of Foo
, which is a singleton (?) instance of a Class
.
This appears to be different from class variables (e.g., @@baz
), which are accessible at the class scope as well as the instance scope.
What, if any, are the downsides to code like the above snippet? Or is it perfectly reasonable code?
Upvotes: 4
Views: 500
Reputation: 1367
The code is valid. You're using class instance variables. As Jörg said, they're generally preferred over class variables. They both can accomplish the same purposes, but class variables have some gotchas. See Class and Instance Variables In Ruby for a good discussion about the pros and cons of class variables versus class instance variables.
One downside to using class instance variables is that they look the same as "normal" instance variables. This can catch new Ruby programmers off guard. The self.print_bar
and print_bar
methods below point to different @bar instance variables.
class Foo
@bar = "bar"
def initialize
@bar = "foo"
end
def self.print_bar
puts @bar #=> "bar"
end
def print_bar
puts @bar #=> "foo"
end
end
This isn't a big downside in my opinion, but you asked :)
The fact that class instance variables are not available to subclasses is not a downside, necessarily. It all depends on how you want the program to behave.
Upvotes: 2
Reputation: 23503
Instance variables that aren't initialized will have a nil
value, while class variables that are not initialize will throw and error. As someone else added, class variables are available to sub-classes.
Here is a link that talks about the two that I found helpful:
http://www.railstips.org/blog/archives/2006/11/18/class-and-instance-variables-in-ruby/
Upvotes: 1
Reputation: 369516
Yes, this is perfectly valid. It is also very widely used and generally recommended over class variables which have a very big scope (the class, all instances of the class, all subclasses, all instances of all subclasses, …).
There are no downsides. Classes are objects. Objects can have instance variables. Nothing to it. Ruby's object model really is much simpler than people, even authors of Ruby tutorials, would make you want to believe.
Upvotes: 6
Reputation: 239372
One potential downside is that @bar
is not available to sub-classes of Foo
.
class Parent
@bar = 3
def self.print_bar
puts @bar # nil
end
end
class Child < Parent
end
Parent.print_bar # 3
Child.print_bar # nil
Upvotes: 3