From: Jarmo Pertman on 1 Aug 2010 15:19 I know that there are methods #kind_of?/#is_a? to check if one object is a same type or a subclass of another object. But what if i want to check if one object is in some module? For example: module MyModule class MyClass end end m = MyModule::MyClass.new m.kind_of?(MyModule) # => false I would be happy if the statement above would return true since MyClass is in module MyModule. Or why wouldn't it (except that it hasn't meant to with current implementation)? Anyway, i was hoping to find some other method for this kind of checks, but was unable to find any from Class, Module, Object, Kernel classes/modules. So i made one example myself: http://gist.github.com/503646 I still think that there should be some easier built-in way to perform this kind of checks. Maybe i have just missed it... Jarmo Pertman ----- IT does really matter - http://www.itreallymatters.net
From: David A. Black on 1 Aug 2010 16:08 Hi -- On Mon, 2 Aug 2010, Jarmo Pertman wrote: > I know that there are methods #kind_of?/#is_a? to check if one object > is a same type or a subclass of another object. But what if i want to > check if one object is in some module? For example: > > module MyModule > class MyClass > end > end > > m = MyModule::MyClass.new > m.kind_of?(MyModule) # => false > > I would be happy if the statement above would return true since > MyClass is in module MyModule. Or why wouldn't it (except that it > hasn't meant to with current implementation)? > > Anyway, i was hoping to find some other method for this kind of > checks, but was unable to find any from Class, Module, Object, Kernel > classes/modules. So i made one example myself: http://gist.github.com/503646 The nesting of classes and modules is completely different from the ancestor/descendant relation, though. It's misleading to combine them. In your example, MyModule is not an ancestor of MyClass, but your descendant? method implies that it is. The ancestor relation (also the basis of kind_of?) is about the method lookup path. If this is true: obj.kind_of?(ModuleOrClass) that means that (unless other arrangements have been made) obj has access to the instance methods defined in ModuleOrClass. It also implies this: obj.class.ancestors.include?(ModuleOrClass) The question of where ModuleOrClass is defined, and how deeply nested it is, is a completely separate question. David -- David A. Black, Senior Developer, Cyrus Innovation Inc. The Ruby training with Black/Brown/McAnally Compleat Philadelphia, PA, October 1-2, 2010 Rubyist http://www.compleatrubyist.com
From: John Croisant on 1 Aug 2010 18:48 On Sun, Aug 1, 2010 at 2:20 PM, Jarmo Pertman <jarmo.p(a)gmail.com> wrote: > I know that there are methods #kind_of?/#is_a? to check if one object > is a same type or a subclass of another object. But what if i want to > check if one object is in some module? For example: > > module MyModule > Â class MyClass > Â end > end > > m = MyModule::MyClass.new > m.kind_of?(MyModule) # => false > > I would be happy if the statement above would return true since > MyClass is in module MyModule. Or why wouldn't it (except that it > hasn't meant to with current implementation)? > > Anyway, i was hoping to find some other method for this kind of > checks, but was unable to find any from Class, Module, Object, Kernel > classes/modules. So i made one example myself: http://gist.github.com/503646 > > I still think that there should be some easier built-in way to perform > this kind of checks. Maybe i have just missed it... > > Jarmo Pertman I would do it this way: MyModule.constants.include?(:MyClass) # note the ":", it's a symbol (It's also possible to define a general method which takes a class, gets the class's name, converts it to a symbol, and then tests whether the module has that constant. But I'll leave that an an excercise for the reader.) Another possible way to do it would be this: MyModule.const_get(:MyClass) This will return MyModule::MyClass if it exists (which will be considered true in an "if" statement), or raise NameError if it doesn't exist. Because it raises an error in the negative case, it's not convenient to use it in an "if" statement, which is why I consider it less desirable than the first way. HTH, - John P.S. I second David's advice not to modify Object#descendant?. The relationship you are testing for is not ancestry/inheritance, so it doesn't make much sense for the #descendant? method to do it.
From: Jarmo Pertman on 2 Aug 2010 07:31 Hello! But the examples provided by you won't work since #constants return only immediate constants and not constants recursively. Thus: irb(main):003:0> module MyModule irb(main):004:1> module AnotherModule irb(main):005:2> class MyClass irb(main):006:3> end irb(main):007:2> irb(main):008:2* class AnotherClass irb(main):009:3> end irb(main):010:2> end irb(main):011:1> end => nil irb(main):012:0> MyModule.constants => ["AnotherModule"] John, what do you even mean by "not to modify Object#descendant?". Object doesn't have any methods named like that - it was just method defined by me. Name of the method didn't have so much importance for me, but the solving of the problem itself. So, both of you think that this solution would be best to do something like this? Or you're saying that i should not do something like this at all? Again, ignore the name of the method itself. Jarmo Pertman ----- IT does really matter - http://www.itreallymatters.net On Aug 2, 1:48 am, John Croisant <jac...(a)gmail.com> wrote: > On Sun, Aug 1, 2010 at 2:20 PM, Jarmo Pertman <jarm...(a)gmail.com> wrote: > > I know that there are methods #kind_of?/#is_a? to check if one object > > is a same type or a subclass of another object. But what if i want to > > check if one object is in some module? For example: > > > module MyModule > > class MyClass > > end > > end > > > m = MyModule::MyClass.new > > m.kind_of?(MyModule) # => false > > > I would be happy if the statement above would return true since > > MyClass is in module MyModule. Or why wouldn't it (except that it > > hasn't meant to with current implementation)? > > > Anyway, i was hoping to find some other method for this kind of > > checks, but was unable to find any from Class, Module, Object, Kernel > > classes/modules. So i made one example myself:http://gist.github.com/503646 > > > I still think that there should be some easier built-in way to perform > > this kind of checks. Maybe i have just missed it... > > > Jarmo Pertman > > I would do it this way: > > MyModule.constants.include?(:MyClass) # note the ":", it's a symbol > > (It's also possible to define a general method which takes a class, > gets the class's name, converts it to a symbol, and then tests whether > the module has that constant. But I'll leave that an an excercise for > the reader.) > > Another possible way to do it would be this: > > MyModule.const_get(:MyClass) > > This will return MyModule::MyClass if it exists (which will be > considered true in an "if" statement), or raise NameError if it > doesn't exist. Because it raises an error in the negative case, it's > not convenient to use it in an "if" statement, which is why I consider > it less desirable than the first way. > > HTH, > > - John > > P.S. I second David's advice not to modify Object#descendant?. The > relationship you are testing for is not ancestry/inheritance, so it > doesn't make much sense for the #descendant? method to do it.
From: Brian Candler on 2 Aug 2010 08:30 Jarmo Pertman wrote: > Hello! > > But the examples provided by you won't work since #constants return > only immediate constants and not constants recursively. Thus: > irb(main):003:0> module MyModule > irb(main):004:1> module AnotherModule > irb(main):005:2> class MyClass > irb(main):006:3> end > irb(main):007:2> > irb(main):008:2* class AnotherClass > irb(main):009:3> end > irb(main):010:2> end > irb(main):011:1> end > => nil > irb(main):012:0> MyModule.constants > => ["AnotherModule"] You can do the following: >> module MyModule >> module AnotherModule >> class MyClass; end >> class AnotherClass; end >> end >> end => nil >> o = MyModule::AnotherModule::MyClass.new => #<MyModule::AnotherModule::MyClass:0xb7436be4> >> o.class.name => "MyModule::AnotherModule::MyClass" >> puts "Yippee" if o.class.name =~ /\bMyModule\b/ Yippee => nil >> puts "Yippee" if o.class.name =~ /\bAnotherModule\b/ Yippee => nil > So, both of you think that this solution would be best to do something > like this? Or you're saying that i should not do something like this > at all? Modules are just namespaces. It seems odd to ask an object what namespace its class is in. As I've shown above, you can do this - but why would you want to? The only time I've wanted to do anything close to this is dynamic constant resolution: module X class Foo N=1 def show_n puts self.class::N end end class Bar < Foo N=2 end end X::Foo.new.show_n # 1 X::Bar.new.show_n # 2 But even then, neither Foo nor Bar cares whether it is inside module X. You can remove the module X wrapper completely, changing X::Foo.new to Foo.new, and it will work just the same. Equally, if it *did* make a difference whether you were inside module X or module Y (perhaps because there were different constants or classes available), then you'd have to write your code differently within those modules anyway. module X N=1 class Foo def yo; puts N; end end end module Y M=2 class Bar def yo; puts M; end end end -- Posted via http://www.ruby-forum.com/.
|
Next
|
Last
Pages: 1 2 Prev: Standard IO streams in Ruby Next: [ANN] RubyConf registration and Call For Proposals now open! |