class C < B < A

  • Thread starter Iñaki Baz Castillo
  • Start date
I

Iñaki Baz Castillo

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 <[email protected]>
 
J

Joel VanderWerf

Iñaki Baz Castillo said:
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?
 
I

Iñaki Baz Castillo

El Martes 07 Abril 2009, Joel VanderWerf escribi=C3=B3:
...

#instance_of? works for all cases except:

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 <[email protected]>
 
S

Siep Korteling

Iñaki Baz Castillo said:
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
 
T

Tim Pease

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

Iñaki Baz Castillo

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 <[email protected]>
 
S

Sean O'Halpin

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
 
R

Robert Klemme

El Martes 07 Abril 2009, Joel VanderWerf escribió:

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

Iñaki Baz Castillo

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 <[email protected]>
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,968
Messages
2,570,153
Members
46,699
Latest member
AnneRosen

Latest Threads

Top