Reputation: 154
I recently saw 2 approaches how to create a class using structs in Ruby:
Customer = Struct.new(:name, :address) do
# ...
end
class Customer < Struct.new(:name, :address)
# ...
end
What's the difference between these approaches?
Upvotes: 3
Views: 46
Reputation: 52357
Some difference is in ancestors chain.
First example:
Customer.ancestors
#=> [Customer, Struct, Enumerable, Object, PP::ObjectMixin, Kernel, BasicObject]
Second example:
Customer.ancestors
#=> [Customer, #<Class:0x007ff4328dddc0>, Struct, Enumerable, Object, PP::ObjectMixin, Kernel, BasicObject]
So in first example Customer
's superclass is a Struct
class itself, whereas in second, it's an anonymous class #<Class:0x007ff4328dddc0>
.
There is also a difference in how the two Customer
's have access to variables of the scope of their definition - see @Зеленый's answer.
Upvotes: 4
Reputation: 44370
Ruby actually has several scopes:
# scope one, opened with `module` keyword
module ...
# scope two, opened with `class` keyword
class ...
end
end
module
, class
some of them.
When you're using the first example you able to share a scope to access the f
variable, it is very handy in some circumstances:
=> f = 1
=> 1
=> Customer = Struct.new(:a) do
=> puts f
=> end
=> 1
=> #<Customer:0x005561498351f8>
With the second example, you can't access f
variable variable:
=> f = 1
=> class Customer < Struct.new(:a)
=> puts f
=> end
#> NameError: undefined local variable or method `f' for Customer:Class
There is also a difference in the ancestors chain - see @AndreyDeineko's answer.
Upvotes: 4