in all the tutorials for RoR I see instances where the coder chose to use Proc.new when seemingly it is both unnecessary and rather unattractive.
Example, here is a callback for placed in a model, one using Proc.new the other presumably doing the same thing:
class Order < ActiveRecord::Base
before_save :normalize_card_number,
:if => Proc.new { |order| order.paid_with_card? }
end
class Order < ActiveRecord::Base
before_save :normalize_card_number, :if => "paid_with_card?"
end
So what's the difference? Why use the Proc? Don't they both call the "paid_with_card?" method?
Thanks in advance
A Proc object is an encapsulation of a block of code, which can be stored in a local variable, passed to a method or another Proc, and can be called. Proc is an essential concept in Ruby and a core of its functional programming features. square = Proc. new {|x| x**2 } square.
Callbacks are methods that get called at certain moments of an object's life cycle. With callbacks it is possible to write code that will run whenever an Active Record object is created, saved, updated, deleted, validated, or loaded from the database.
In the example above, using a symbol for the conditional method would probably be the best choice.
class Order < ActiveRecord::Base
before_save :normalize_card_number, :if => :paid_with_card?
end
The string option uses eval to evaluate the Ruby code in the string. So personally, I would prefer to use a symbol if calling a method or a Proc if writing a short inline condition.
Per the RailsGuides documentation:
Using a Proc object gives you the ability to write an inline condition instead of a separate method. This option is best suited for one-liners.
I think using a Proc might be better illustrated this way:
class Order < ActiveRecord::Base
before_save :normalize_card_number,
:if => Proc.new { |order| order.payment_type == "card" }
end
This would possibly eliminate the need for the paid_with_card? method.
I'd say it was the case that in older versions of Rails that's how we used to do things, and someone added the feature whereby you could pass a string to be evaluated as an instance method on the current model.
In simple scenarios it makes the older style redundant, but allows for the use of a Proc for more complex 'if' statements which would be impossible to achieve using a method on only the current instance.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With