[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

class C < B < A

Iñaki Baz Castillo

4/6/2009 10:13:00 PM

Hi, I have this case:

class A ; end
class B < A ; end
class C < B ; end

a =3D A.new
b =3D B.new
c =3D C.new


I look for a way (***) to get the following results:

a)
a *** A =3D> true
a *** B =3D> false
a *** C =3D> false

b)
b *** A =3D> false (*1)
b *** B =3D> true
b *** C =3D> false

c)
c *** A =3D> false (*2)
c *** B =3D> true
c *** C =3D> true


Note that I could use =3D=3D=3D, so:
A =3D=3D=3D a =3D> true
A =3D=3D=3D b =3D> false

but in cases *1 and *2 the result is not what I want:

A =3D=3D=3D b =3D> true (I want false)
A =3D=3D=3D c =3D> true (I want false)


I could play with a.class.ancestors, but isn't another way?

Thanks a lot.

=2D-=20
I=C3=B1aki Baz Castillo <ibc@aliax.net>

9 Answers

Joel VanderWerf

4/6/2009 10:34:00 PM

0

Iñaki Baz Castillo wrote:
> Hi, I have this case:
>
> class A ; end
> class B < A ; end
> class C < B ; end
>
> a = A.new
> b = B.new
> c = C.new
>
>
> I look for a way (***) to get the following results:
...

#instance_of? works for all cases except:

> c *** B => true

Are you sure you need this to be true?

--
vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

Iñaki Baz Castillo

4/6/2009 10:42:00 PM

0

El Martes 07 Abril 2009, Joel VanderWerf escribi=C3=B3:
> I=C3=B1aki Baz Castillo wrote:
> > Hi, I have this case:
> >
> > class A ; end
> > class B < A ; end
> > class C < B ; end
> >
> > a =3D A.new
> > b =3D B.new
> > c =3D C.new
> >
> >
> > I look for a way (***) to get the following results:
>
> ...
>
> #instance_of? works for all cases except:
> > c *** B =3D> true
>
> Are you sure you need this to be true?

Yes. Basically A is String and B is a child of String with various methods,=
=20
and C is a more specific class.

But I didn't realize of #instance_of?, I will try with it.

Thanks.

=2D-=20
I=C3=B1aki Baz Castillo <ibc@aliax.net>

Siep Korteling

4/6/2009 10:48:00 PM

0

Iñaki Baz Castillo wrote:
> Hi, I have this case:
>
> class A ; end
> class B < A ; end
> class C < B ; end
>
> a = A.new
> b = B.new
> c = C.new
>
>
> I look for a way (***) to get the following results:
>
> a)
> a *** A => true
> a *** B => false
> a *** C => false
>
> b)
> b *** A => false (*1)
> b *** B => true
> b *** C => false
>
> c)
> c *** A => false (*2)
> c *** B => true
> c *** C => true
>
(...)
> Thanks a lot.

The method #kind_of? gives the results you want.

regards,

Siep


--
Posted via http://www.ruby-....

Iñaki Baz Castillo

4/6/2009 10:55:00 PM

0

El Martes 07 Abril 2009, Siep Korteling escribi=C3=B3:
> I=C3=B1aki Baz Castillo wrote:

> > a)
> > a *** A =3D> true
> > a *** B =3D> false
> > a *** C =3D> false
> >
> > b)
> > b *** A =3D> false (*1)

b.kind_of? A
=3D> true


> > b *** B =3D> true
> > b *** C =3D> false
> >
> > c)
> > c *** A =3D> false (*2)

c.kind_of? A
=3D> true

> > c *** B =3D> true
> > c *** C =3D> true
>
> (...)
>
> > Thanks a lot.
>
> The method #kind_of? gives the results you want.

Not in the above cases. It's the same as using =3D=3D=3D :(

=2D-=20
I=C3=B1aki Baz Castillo <ibc@aliax.net>

Tim Pease

4/6/2009 11:09:00 PM

0


On Apr 6, 2009, at 4:12 PM, I=F1aki Baz Castillo wrote:

> Hi, I have this case:
>
> class A ; end
> class B < A ; end
> class C < B ; end
>
> a =3D A.new
> b =3D B.new
> c =3D C.new
>
>
> I look for a way (***) to get the following results:
>
> a)
> a *** A =3D> true
> a *** B =3D> false
> a *** C =3D> false
>
> b)
> b *** A =3D> false (*1)
> b *** B =3D> true
> b *** C =3D> false
>
> c)
> c *** A =3D> false (*2)
> c *** B =3D> true
> c *** C =3D> true
>
>
> Note that I could use =3D=3D=3D, so:
> A =3D=3D=3D a =3D> true
> A =3D=3D=3D b =3D> false
>
> but in cases *1 and *2 the result is not what I want:
>
> A =3D=3D=3D b =3D> true (I want false)
> A =3D=3D=3D c =3D> true (I want false)
>

Well, it's kinda hackish but it does give the correct output. Tailor =20
to suit your needs:


class A
alias :like? :instance_of?
end

class B < A; end

class C < B
def like?( clazz )
return true if clazz =3D=3D B
super
end
end

a =3D A.new
b =3D B.new
c =3D C.new

[A, B, C].each do |clazz|
puts "a.like? #{clazz.name} =3D> #{a.like? clazz}"
end
puts

[A, B, C].each do |clazz|
puts "b.like? #{clazz.name} =3D> #{b.like? clazz}"
end
puts

[A, B, C].each do |clazz|
puts "c.like? #{clazz.name} =3D> #{c.like? clazz}"
end


=3D=3D=3D=3D OUTPUT =3D=3D=3D=3D
a.like? A =3D> true
a.like? B =3D> false
a.like? C =3D> false

b.like? A =3D> false
b.like? B =3D> true
b.like? C =3D> false

c.like? A =3D> false
c.like? B =3D> true
c.like? C =3D> true


Again, I'm not proud of this code -- it works, though, without being =20
too tricky.

Blessings,
TwP=

Iñaki Baz Castillo

4/6/2009 11:11:00 PM

0

El Martes 07 Abril 2009, Tim Pease escribi=F3:
> =3D=3D=3D=3D OUTPUT =3D=3D=3D=3D
> a.like? A =3D> true
> a.like? B =3D> false
> a.like? C =3D> false
>
> b.like? A =3D> false
> b.like? B =3D> true
> b.like? C =3D> false
>
> c.like? A =3D> false
> c.like? B =3D> true
> c.like? C =3D> true
>
>
> Again, I'm not proud of this code -- it works, though, without being
> too tricky.

So freak! :)

Thanks a lot.


=2D-=20
I=F1aki Baz Castillo <ibc@aliax.net>

Sean O'Halpin

4/7/2009 12:38:00 AM

0

On Mon, Apr 6, 2009 at 11:12 PM, I=F1aki Baz Castillo <ibc@aliax.net> wrote=
:
> Hi, I have this case:
>
> =A0class A =A0 =A0 ; end
> =A0class B < A ; end
> =A0class C < B ; end
>
> =A0a =3D A.new
> =A0b =3D B.new
> =A0c =3D C.new
>
>
> I look for a way (***) to get the following results:
>
> a)
> =A0a *** A =3D> true
> =A0a *** B =3D> false
> =A0a *** C =3D> false
>
> b)
> =A0b *** A =3D> false =A0(*1)
> =A0b *** B =3D> true
> =A0b *** C =3D> false
>
> c)
> =A0c *** A =3D> false =A0(*2)
> =A0c *** B =3D> true
> =A0c *** C =3D> true
>
>
> Note that I could use =3D=3D=3D, so:
> =A0A =3D=3D=3D a =3D> true
> =A0A =3D=3D=3D b =3D> false
>
> but in cases *1 and *2 the result is not what I want:
>
> =A0A =3D=3D=3D b =3D> true (I want false)
> =A0A =3D=3D=3D c =3D> true (I want false)
>
>
> I could play with a.class.ancestors, but isn't another way?
>
> Thanks a lot.
>

You need to specify somewhere the root of the inheritance hierarchy
you're interested in. Something like this:

class A
def like?(klass)
if klass =3D=3D A
self.class =3D=3D A
else
self.class <=3D klass
end
end
end

More generally, this will do what you want (at least, what I think you want=
;)

module RootedClassComparison
def self.included(other)
module_eval {
define_method :like? do |klass|
if klass =3D=3D other
self.class =3D=3D other
else
self.class <=3D klass
end
end
}
end
end

class A
include RootedClassComparison
end
class B < A
end
class C < B
end
class D < C
end


a =3D A.new
b =3D B.new
c =3D C.new
d =3D D.new

klasses =3D [A, B, C, D]

# test pinched from Tim's example :)
klasses.each do |clazz|
puts "a.like? #{clazz.name} =3D> #{a.like? clazz}"
end
puts

klasses.each do |clazz|
puts "b.like? #{clazz.name} =3D> #{b.like? clazz}"
end
puts

klasses.each do |clazz|
puts "c.like? #{clazz.name} =3D> #{c.like? clazz}"
end
puts

klasses.each do |clazz|
puts "d.like? #{clazz.name} =3D> #{d.like? clazz}"
end

Output:

a.like? A =3D> true
a.like? B =3D> false
a.like? C =3D> false
a.like? D =3D> false

b.like? A =3D> false
b.like? B =3D> true
b.like? C =3D> false
b.like? D =3D> false

c.like? A =3D> false
c.like? B =3D> true
c.like? C =3D> true
c.like? D =3D> false

d.like? A =3D> false
d.like? B =3D> true
d.like? C =3D> true
d.like? D =3D> true

Regards,
Sean

Robert Klemme

4/7/2009 7:47:00 AM

0

On 07.04.2009 00:41, Iñaki Baz Castillo wrote:
> El Martes 07 Abril 2009, Joel VanderWerf escribió:
>> Iñaki Baz Castillo wrote:
>>> Hi, I have this case:
>>>
>>> class A ; end
>>> class B < A ; end
>>> class C < B ; end
>>>
>>> a = A.new
>>> b = B.new
>>> c = C.new
>>>
>>>
>>> I look for a way (***) to get the following results:
>> ...
>>
>> #instance_of? works for all cases except:
>>> c *** B => true
>> Are you sure you need this to be true?
>
> Yes. Basically A is String and B is a child of String with various methods,
> and C is a more specific class.

Frankly, I find this a bit spooky for several reasons: first, you
inherit String which IMHO is almost always a bad idea(tm). You should
consider using delegation, so you have

class B
attr_reader :str
end

class C < B; end

Then, you introduce inconsistencies in inheritance checking. That might
yield all sorts of surprises.

If you want to do it nevertheless, I'd probably go for a special method
which you override appropriately:

class Module
def class_of?(obj)
if self == String
self == obj.class
else
self === obj
end
end
end

class B < String
end

class C < B
end

classes = [String,B,C]
classes.each do |cl|
puts cl
o = cl.new

classes.each do |cl2|
print cl2, " ", cl2.class_of?(o), "\n"
end

puts "--"
end


Something along these lines.

Kind regards

robert

Iñaki Baz Castillo

4/7/2009 6:26:00 PM

0

El Martes 07 Abril 2009, Robert Klemme escribi=F3:
> Frankly, I find this a bit spooky for several reasons: first, you
> inherit String which IMHO is almost always a bad idea(tm). You should
> consider using delegation, so you have

Thanks a lot. However I've already solved it by changing my classes=20
definitions so I don't have that painful requeriment anymore :)

=2D-=20
I=F1aki Baz Castillo <ibc@aliax.net>