Reputation: 5562
I came across this question and the answer from @Kris has the line:
end.new
here:
subject do
Class.new do
include ActiveModel::Validations
attr_accessor :email
validates :email, email: true
end.new
end
I have not seen that before and cannot find other examples nor explanations.
Why not just 'end' on it's own, like this:
subject do
Class.new do
include ActiveModel::Validations
attr_accessor :email
validates :email, email: true
end
end
What is the difference?
Upvotes: 1
Views: 118
Reputation: 26778
First of all you need to understand that you can chain statements on end
, for example
[1,2,3,4,5].select do |num|
i % 2 == 0
end.map do |num|
"#{num} is even"
end.each do |str|
puts str
end
Next, to understand your example you need to understand what is an "anonymous" class.
You can define this class normally instead:
class MyClass
include ActiveModel::Validations
attr_accessor :email
validates :email, email: true
end
and you will have defined a global MyClass
variable that refers to the class. Of course, you can call MyClass.new
to get an instance.
The anomymous class block Class.new do
is the same thing but it doesn't define a global identifer for the class. Instead, to get a handle on the class you must assign a variable to the result of the Class.new do .. end
expression.
So, if you understand that Class.new do ... end
returns a class, and you can call .new
on any class, then you can do something like the code in your question:
klass = Class.new { def foo; "bar"; end }
klass.new.foo # => "bar"
# or ...
Class.new { def foo; "bar"; end }.new.foo # => "bar"
do ... end
being the multiline version of {}
to define a block
Upvotes: 3