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
Note that I could use ===, so:
A === a => true
A === b => false
but in cases *1 and *2 the result is not what I want:
A === b => true (I want false)
A === c => true (I want false)
I could play with a.class.ancestors, but isn't another way?
Thanks a lot.
···
--
Iñaki Baz Castillo <ibc@aliax.net>
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 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-forum.com/\.
Well, it's kinda hackish but it does give the correct output. Tailor 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 == B
super
end
end
a = A.new
b = B.new
c = C.new
[A, B, C].each do |clazz|
puts "a.like? #{clazz.name} => #{a.like? clazz}"
end
puts
[A, B, C].each do |clazz|
puts "b.like? #{clazz.name} => #{b.like? clazz}"
end
puts
[A, B, C].each do |clazz|
puts "c.like? #{clazz.name} => #{c.like? clazz}"
end
==== OUTPUT ====
a.like? A => true
a.like? B => false
a.like? C => false
b.like? A => false
b.like? B => true
b.like? C => false
c.like? A => false
c.like? B => true
c.like? C => true
Again, I'm not proud of this code -- it works, though, without being too tricky.
Blessings,
TwP
···
On Apr 6, 2009, at 4:12 PM, 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
Note that I could use ===, so:
A === a => true
A === b => false
but in cases *1 and *2 the result is not what I want:
A === b => true (I want false)
A === c => true (I want false)
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 == A
self.class == A
else
self.class <= 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 == other
self.class == other
else
self.class <= klass
end
end
}
end
end
class A
include RootedClassComparison
end
class B < A
end
class C < B
end
class D < C
end
a = A.new
b = B.new
c = C.new
d = D.new
klasses = [A, B, C, D]
# test pinched from Tim's example 
klasses.each do |clazz|
puts "a.like? #{clazz.name} => #{a.like? clazz}"
end
puts
klasses.each do |clazz|
puts "b.like? #{clazz.name} => #{b.like? clazz}"
end
puts
klasses.each do |clazz|
puts "c.like? #{clazz.name} => #{c.like? clazz}"
end
puts
klasses.each do |clazz|
puts "d.like? #{clazz.name} => #{d.like? clazz}"
end
Output:
a.like? A => true
a.like? B => false
a.like? C => false
a.like? D => false
b.like? A => false
b.like? B => true
b.like? C => false
b.like? D => false
c.like? A => false
c.like? B => true
c.like? C => true
c.like? D => false
d.like? A => false
d.like? B => true
d.like? C => true
d.like? D => true
Regards,
Sean
···
On Mon, Apr 6, 2009 at 11:12 PM, Iñaki Baz Castillo <ibc@aliax.net> 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
Note that I could use ===, so:
A === a => true
A === b => false
but in cases *1 and *2 the result is not what I want:
A === b => true (I want false)
A === c => true (I want false)
I could play with a.class.ancestors, but isn't another way?
Thanks a lot.
Yes. Basically A is String and B is a child of String with various methods,
and C is a more specific class.
But I didn't realize of #instance_of?, I will try with it.
Thanks.
···
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?
--
Iñaki Baz Castillo <ibc@aliax.net>
Iñaki Baz Castillo wrote:
> a)
> a *** A => true
> a *** B => false
> a *** C => false
>
> b)
> b *** A => false (*1)
b.kind_of? A
=> true
> b *** B => true
> b *** C => false
>
> c)
> c *** A => false (*2)
c.kind_of? A
=> true
> c *** B => true
> c *** C => true
(...)
> Thanks a lot.
The method #kind_of? gives the results you want.
Not in the above cases. It's the same as using === 
···
El Martes 07 Abril 2009, Siep Korteling escribió:
--
Iñaki Baz Castillo <ibc@aliax.net>
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
···
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.
Thanks a lot. However I've already solved it by changing my classes
definitions so I don't have that painful requeriment anymore 
···
El Martes 07 Abril 2009, Robert Klemme escribió:
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
--
Iñaki Baz Castillo <ibc@aliax.net>