From: Andrea Dallera Date: 2012-08-06T02:48:12+09:00 Subject: Re: Redefining constants for a given instance only --_=__=_XaM3_.1344188884.2A.337247.42.25756.52.42.007.1606807353 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable =C2=A0Hi Robert,=0A=0A=C2=A0 =C2=A0 thanks for your reply.=C2=A0=0A=0A>=C2= =A0That can lead to confusion with regard to the class names.=0A=0AI know= , but that shouldn't cause me problems in this particular case.=0A=0AUnfo= rtunately, I'd like to avoid storing the class in a variable and then ref= erring to it because then the code inside what I called Evaluator would h= ave to be aware of the mechanics. The method Evaluator#evaluate might als= o 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 define= d:=0A=0Aclass A; end=0Aclass B; end=0Aclass C; end=0A=0Aclass Evaluator=0A= =C2=A0 def evaluate=0A=C2=A0 =C2=A0 =C2=A0#complex expression using one o= r more among A,B,C, like for example=0A=C2=A0 =C2=A0 =C2=A0A.method1 =3D=3D= :test && @myvar.is_a?(B) && C.method2 =3D=3D :other_test=0A=C2=A0 end=0A= end=0A=0Amind that the swap should happen only for a given instance of Ev= aluator, not at the class level, in a way such as=0A=0Aev1 =3D Evaluator.= new=0Aev2 =3D Evaluator.new=0Aev1.set(A).to(B) #something like this, or w= orse named ev1.set(A,B) for simplicity=C2=A0=0Aev1.evaluate #here, A.is_a= ?(B)#true.=0Aev2.evaluate #here, not so=0A=0AI'm not even sure if that's = possible to do in ruby at this point. Opening the singleton class (class = << ev1) and defining the constant there works (in the sense that the sing= leton class has the constant correctly =C2=A0changed) but the methods def= ined on the class correctly ignore it.=0A=0AIn any case, thanks for your = time :-)=0A=0AAndrea=0A--=0A=0Ahttp://usingimho.wordpress.com=0Ahttp://gi= thub.com/bolthar=0AFrom: "Robert Klemme" shortcutter@googlemail.com=0ATo:= ruby-talk@ruby-lang.org=0ACc: =0ADate: Mon, 6 Aug 2012 02:28:09 +0900=0A= Subject: Re: Redefining constants for a given instance only=0A=0A> On Sun= , Aug 5, 2012 at 7:19 PM, Andrea Dallera wrote:=0A> > Hello,=0A> >=0A> >= let's say we have two empty classes:=0A> >=0A> > class ClassA=0A> >=0A= > > end=0A> >=0A> > class ClassB=0A> >=0A> > end=0A> >=0A> > then we have= a third one, which has a method that references the first=0A> > class:=0A= > >=0A> > class Evaluator=0A> >=0A> > def evaluate=0A> > return= ClassA=0A> > end=0A> >=0A> > end=0A> >=0A> > What I'd like to do is t= o be able to redefine what ClassA is for a given=0A> > instance of Evalua= tor, like so:=0A> >=0A> > ev =3D Evaluator.new=0A> > =0A> > ev.evaluate #= ClassB=0A> >=0A> > I found out how to do this, but only class-wide:=0A> >= =0A> > ev =3D Evaluator.new=0A> > ev.evaluate #ClassA=0A> > class Evaluat= or=0A> > ClassA =3D ClassB=0A> > end=0A> > ev.evaluate #ClassB=0A> =0A>= That can lead to confusion with regard to the class names.=0A> =0A> > Id= eas?=0A> =0A> Well, the simplest is to just store it in a member.=0A> =0A= > irb(main):001:0> Evaluator =3D Struct.new :other_class do=0A> irb(main)= :002:1* def evaluate; other_class; end=0A> irb(main):003:1> end=0A> =3D> = Evaluator=0A> irb(main):004:0> class A;end=0A> =3D> nil=0A> irb(main):005= :0> class B;end=0A> =3D> nil=0A> irb(main):006:0> e1 =3D Evaluator.new A=0A= > =3D> #=0A> irb(main):007:0> e1.evaluate=0A> =3D> A=0A> irb(main):008:0>= e2 =3D Evaluator.new B=0A> =3D> #=0A> irb(main):009:0> e2.evaluate=0A> =3D= > B=0A> =0A> Note: you do not necessarily need the Struct, I just picked = it because=0A> that saved me a bit of typing.=0A> =0A> Kind regards=0A> =0A= > robert=0A> =0A> =0A> -- =0A> remember.guy do |as, often| as.you_can - w= ithout end=0A> http://blog.rubybestpractices.com/=0A> --_=__=_XaM3_.1344188884.2A.337247.42.25756.52.42.007.1606807353 Content-Type: text/html; charset=utf-8 Content-Transfer-Encoding: quoted-printable =0A
=0A
 Hi Robert,

    thanks for your reply. 

>= ; That can lead to confusion with regard to the class names.

I know, but that shouldn't cause me problems in this pa= rticular case.

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 mechan= ics. The method Evaluator#evaluate might also refer to more than one cons= tant and, ideally, shouldn't be at all aware that one of the constant it'= s using is not what it originally was defined:

c= lass A; end
class B; end
class C; end

<= /div>
class Evaluator
  def evaluate
  =    #complex expression using one or more among A,B,C, like for = example
     A.method1 =3D=3D :test && @= myvar.is_a?(B) && C.method2 =3D=3D :other_test
  e= nd
end

mind that the swap should happe= n only for a given instance of Evaluator, not at the class level, in a wa= y such as

ev1 =3D Evaluator.new
ev2 =3D= Evaluator.new
ev1.set(A).to(B) #something like this, or worse = named ev1.set(A,B) for simplicity 
ev1.evaluate #here, A.i= s_a?(B)#true.
ev2.evaluate #here, not so

I'm not even sure if that's possible to do in ruby at this point. Open= ing the singleton class (class << ev1) and defining the constant th= ere works (in the sense that the singleton class has the constant correct= ly  changed) but the methods defined on the class correctly ignore i= t.

In any case, thanks for your time :-)

Andrea
--

http://usi= ngimho.wordpress.com
http://github.com/bolthar


=0A=
Fr= om: "Robert Klemme" shortcutter@googlemail.com=0A
To: ruby-talk@ruby-lang.org
=0A
Cc= :
=0A
Date: Mon, 6 Aug 2012 02:28:= 09 +0900
=0A
Subject: Re: Redefining constants= for a given instance only
=0A
=0A
> On Sun, Aug 5,= 2012 at 7:19 PM, Andrea Dallera wrote:
> > Hello,
> >
=
> > let's say we have two empty classes:
> &g= t;
> > class ClassA
> >
> &g= t; end
> >
> > class ClassB
>= ; >
> > end
> >
> > th= en we have a third one, which has a method that references the first
> > class:
> >
> > class Eval= uator
> >
> > def evaluate
&= gt; > return ClassA
> > end
> &= gt;
> > end
> >
> > What = I'd like to do is to be able to redefine what ClassA is for a given
=
> > instance of Evaluator, like so:
> >
<= div>> > ev =3D Evaluator.new
> >
> > ev.evaluate #ClassB
> >= ;
> > I found out how to do this, but only class-wide:
> >
> > ev =3D Evaluator.new
>= > ev.evaluate #ClassA
> > class Evaluator
&= gt; > ClassA =3D ClassB
> > end
> > = ev.evaluate #ClassB
>
> That can lead to confu= sion with regard to the class names.
>
> > = Ideas?
>
> Well, the simplest is to just store= it in a member.
>
> irb(main):001:0> Evalu= ator =3D Struct.new :other_class do
> irb(main):002:1* def e= valuate; other_class; end
> irb(main):003:1> end
> =3D> Evaluator
> irb(main):004:0> class A;end
> =3D> nil
> irb(main):005:0> class B;end<= /div>
> =3D> nil
> irb(main):006:0> e1 =3D Eval= uator.new A
> =3D> #
> irb(main):007:0> e1.evaluate
&g= t; =3D> A
> irb(main):008:0> e2 =3D Evaluator.new B
> =3D> #<= /div>
> irb(main):009:0> e2.evaluate
> =3D> B
>
> Note: you do not necessarily need the Struc= t, I just picked it because
> that saved me a bit of typing.=
>
> Kind regards
>
&g= t; robert
>
>
> --
&g= t; remember.guy do |as, often| as.you_can - without end
> ht= tp://blog.rubybestpractices.com/
>
=0A
=0A --_=__=_XaM3_.1344188884.2A.337247.42.25756.52.42.007.1606807353--