We use Structs in Ruby to create simple classes with constructor and some instance variables.
Look at this simple User
class:
class User
attr_accessor :first_name, :last_name, :age
def initialize(first_name, last_name, age)
@first_name = first_name
@last_name = last_name
@age = age
end
end
Using Struct, you can simply use a single line instead of declaring attr_accessor
s and constructor and the class will have exactly the same API:
User = Struct.new(:first_name, :last_name, :age)
But when it comes to a class with internal resources like constants, you may get a warning:
User = Struct.new(:first_name, :last_name, :age) do
MIN_AGE = 18
# some methods dealing with user
end
Admin = Struct.new(:first_name, :last_name, :age) do
MIN_AGE = 21
end
# => warning: already initialized constant MIN_AGE
# => warning: previous definition of MIN_AGE was here
What happends here? We assumed that MIN_AGE
was declared inside User
and Admin
, but actually it was declared on the top level:
> Object::MIN_AGE
=> 18
And warnings were printed.
But wait, there is actually a proper way to subclass from Struct:
class User < Struct.new(:first_name, :last_name, :age)
LIMIT = 1
end
class Admin < Struct.new(:first_name, :last_name, :age)
MIN_AGE = 21
end
No warnings here!
I also recommend you to check it the post by Steve Klabnik, where he describes all power of Struct.