I have some classes that will do something based on some conditions . The conditions are sent as parameters to some methods . My questions is related to ruby coding style :
should the conditions be sent as lambdas/blocks , or as some objects that inherit from a condition class ?
which is more efficient in terms of OOP ?
Thanks !
-
I don't know which is more efficient from an execution time perspective, but blocks are more efficient from a user interface perspective. The person using your method just writes the condition in a block instead of having to define a whole new class, create an instance, and pass it to your method.
Geo : What about a large project ? Long term projects ?Glomek : Saving yourself time and code on boilerplate stuff is even more important in large projects. -
Lambdas are more the Ruby way — and besides that, why define a whole big class for something a simple lambda does just fine? Alternatively, you could pass conditions as a Hash like Rails tends to do.
Geo : What if I need to setup my classes with more than one condition ? Where would I store all the conditions ? A namespace containing a hash and a whole bunch of conditions as hash values?Chuck : You haven't given any information about the structure of your program beyond that it "will do something based on some conditions," so I have no idea where you'd store anything. -
The only case in wich I would use inheritance in this situation, is if the conditions themselves use many common code, that can be completely implemented in the superclass (without need to override anything in the subclases), but the practice of using inheritance for java style interfaces is not usual in Ruby.
In any case, what you are doing is known as inversion of control and strategy patterns, read about that for more information. The key being the (good) decision of making the user of the code decide what the final behaviour of your code would be, as opossed to a configuration parameter or some other sort of branching in the implementation.
-
It's all negligible and it depends on what your actually doing and whether condition objects or procs could be cached, but in general blocks are the Ruby way and they are faster than object creation.
Here's a useless benchmark:
require 'benchmark' # Useless parent class class Condition; end # Useless inheritance. Duck typing FTW. class AddCondition < Condition def call 1 + 1 end end def with_object(condition) condition.call end def with_block yield end n = 100000 Benchmark.bm(10) do |x| x.report("object:") do n.times do; with_object(AddCondition.new); end end x.report("block:") do n.times do; with_block { 1 + 1 }; end end end
And the results:
user system total real object: 0.090000 0.000000 0.090000 ( 0.087227) block: 0.060000 0.000000 0.060000 ( 0.063736)
Geo : We could explain that because creating an object is more expensive than adding two values together.Ryan McGeary : @Donovan, it's more than just adding two values together; the block is created as well. There is still overhead in keeping a reference to the stack that is used by the _closure_.Ryan McGeary : ...but yes, Object creation is more expensive.
0 comments:
Post a Comment