We use Structs in Ruby to create simple classes with constructor and some instance variables.
Look at this simple User
class:
{% highlight ruby %} 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 {% endhighlight %}
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:
{% highlight ruby %} User = Struct.new(:first_name, :last_name, :age) {% endhighlight %}
But when it comes to a class with internal resources like constants, you may get a warning:
{% highlight ruby %} 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
{% endhighlight %}
What happends here? We assumed that MIN_AGE
was declared inside User
and Admin
, but actually it was declared on the top level:
{% highlight ruby %}
Object::MIN_AGE => 18 {% endhighlight %}
And warnings were printed.
But wait, there is actually a proper way to subclass from Struct:
{% highlight ruby %} 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 {% endhighlight %}
No warnings here!
I also recommend you to check it the post by Steve Klabnik, where he describes all power of Struct.