From: Josh Cheek Date: 2012-08-07T22:41:47+09:00 Subject: Re: Redefining constants for a given instance only --f46d043c7fa2bcf00e04c6ad270d Content-Type: text/plain; charset=ISO-8859-1 On Sun, Aug 5, 2012 at 12:48 PM, Andrea Dallera wrote: > > Unfortunately, I'd like to avoid storing the class in a variable and then > referring to it because then the code inside what I called Evaluator would > have to be aware of the mechanics. The method Evaluator#evaluate might also > refer to more than one constant and, ideally, shouldn't be at all aware > that one of the constant it's using is not what it originally was defined: > > I don't really understand why you can't pass it in when you initialize. Are you saying that the implementation of #evaluate isn't known? Can't you just scroll down a bit and see it? Or are you overriding it in subclasses or something? If so, it sounds like you need to pull out an object that wraps the evaluate method, then you can initialize the evaluator (which would perhaps be misnamed if you do this) with that object, and your evaluate method could just delegate to it: class MoreThanN def initialize(n) @n = n end def call(value) value > @n end end class IsEven def call(value) value.even? end end # in this contrived example, this class is irrelevant, # but presumably in your more complex domain, it does something useful class Evaluator def initialize(strategy) @strategy = strategy end def evaluate(value) @strategy.call value end end Evaluator.new(MoreThanN.new 3).evaluate 2 # => false Evaluator.new(MoreThanN.new 3).evaluate 4 # => true Evaluator.new(IsEven.new).evaluate 3 # => false Evaluator.new(IsEven.new).evaluate 4 # => true --f46d043c7fa2bcf00e04c6ad270d Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable On Sun, Aug 5, 2012 at 12:48 PM, Andrea Dallera <andrea@andreadalle= ra.com> wrote:
=A0
=
Unfortunately, I'd like to avoid storing the class in a vari= able and then referring to it because then the code inside what I called Ev= aluator would have to be aware of the mechanics. The method Evaluator#evalu= ate might also refer to more than one constant and, ideally, shouldn't = be at all aware that one of the constant it's using is not what it orig= inally was defined:


I don't rea= lly understand why you can't pass it in when you initialize. Are you sa= ying that the implementation of #evaluate isn't known? Can't you ju= st scroll down a bit and see it? Or are you overriding it in subclasses or = something?

If so, it sounds like you need to pull out an object th= at wraps the evaluate method, then you can initialize the evaluator (which = would perhaps be misnamed if you do this) with that object, and your evalua= te method could just delegate to it:


class MoreThanN
=A0 def initialize(n)
=A0=A0=A0 @n =3D n
= =A0 end
=A0
=A0 def call(value)
=A0=A0=A0 value > @n
=A0 en= d
end


class IsEven
=A0 def call(value)
=A0=A0=A0 value.= even?
=A0 end
end


# in this contrived example, this class is irrelevant,
# but presuma= bly in your more complex domain, it does something useful
class Evaluato= r
=A0 def initialize(strategy)
=A0=A0=A0 @strategy =3D strategy
= =A0 end
=A0
=A0 def evaluate(value)
=A0=A0=A0 @strategy.call value
=A0 en= d
end


Evaluator.new(MoreThanN.new 3).evaluate 2 # =3D> fal= se
Evaluator.new(MoreThanN.new 3).evaluate 4 # =3D> true
Evaluator= .new(IsEven.new).evaluate=A0=A0=A0=A0=A0 3 # =3D> false
Evaluator.new(IsEven.new).evaluate=A0=A0=A0=A0=A0 4 # =3D> true

<= /div> --f46d043c7fa2bcf00e04c6ad270d--