SvenDittmer
SvenDittmer

Reputation: 154

What's the difference between the different approaches to creating classes from structs?

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

Answers (2)

Andrey Deineko
Andrey Deineko

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

Roman Kiselenko
Roman Kiselenko

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

Related Questions