论坛首页 Ruby版

被ruby搞晕了

浏览 6341 次
该帖已经被评为良好帖
作者 正文
时间:2006-09-27
我理解的前提:
一个ruby对象obj,要想obj.respond_to?(:method)为真,必须obj.class.instance_methods.index("method")不是nil。

也就是说,obj.method里面,method必须是instance_method。而不象java那样,class method也可见。

这可以通过实验证实:
class Rubbish
  def self.kick
  end
end
assert_equals(false, Rubbish.new.respond_to?(:kick))


如果是这样,ruby的method lookup方式就很好理解了。

但是下面一个实验却又推翻了我的假设:
class Object
  def self.bizzare
    puts 'bizzare'
  end
end
assert_equals(false, Module.class.instance_methods.index("bizzare"))
assert_equals(true, Module.respond_to?(:bizzare))


怎么回事?为什么这里面Module这个对象可以接受bizzare,可是bizzare却不是它的instance method?

彻底晕了!
   
时间:2006-09-27
bizzare是Module的类方法啊,不是实例方法

引用
一个ruby对象obj,要想obj.respond_to?(:method)为真,必须obj.class.instance_methods.index("method")不是nil。

这句话只在obj是实例对象时才成立:
Rubbish.respond_to? :kick #=>true
Rubbish.class.instance_methods.include? :kick #=> false ,类的类等于Class 
Rubbish.methods.include? :kick #=> true
   
0 请登录后投票
时间:2006-09-27
cookoo 写道
bizzare是Module的类方法啊,不是实例方法

引用
一个ruby对象obj,要想obj.respond_to?(:method)为真,必须obj.class.instance_methods.index("method")不是nil。

这句话只在obj是实例对象时才成立:
Rubbish.respond_to? :kick #=>true
Rubbish.class.instance_methods.include? :kick #=> false ,类的类等于Class 
Rubbish.methods.include? :kick #=> true



Module也是一个对象呀。所以Module.some_method其实应该就是对Module对象调用实力方法

Module作为一个对象,应该和普通对象有一样的规则把?
   
0 请登录后投票
时间:2006-09-27
 class Rubbish                             
   class << self                           
     self.instance_methods.include? "kick" #=> true
   end                                     
 end

类是对象,但是类方法是定义在类的单子类里的实例方法,而不是定义在所有类的类Class里面的实例方法
   
0 请登录后投票
时间:2006-09-27
bizzare如果定义在Module内部,Rubbish.bizzare就访问不了。

定义在Object内部就可以。

class Object
  def self.bizzare
  end
end
class Module
  def self.bizzare2
  end
end
class Rubbish
end

Rubbish.bizzare # ok
Rubbish.bizzare2 # fail
   
0 请登录后投票
时间:2006-09-27
引用
这句话只在obj是实例对象时才成立

定义一下,什么叫“实例对象”?Module不是实例对象?Rubbish不是?

Module和Rubbish其实都是Class的实例。
   
0 请登录后投票
时间:2006-09-27
irb(main):001:0> class Object; def self.test; puts "test method"; end; end
=> nil
irb(main):002:0> Object.test
test method
=> nil
irb(main):003:0> Module.test
test method
=> nil
irb(main):004:0> Module.superclass == Object
=> true
irb(main):005:0> Module.singleton_methods.include?("test")
=> true
   
0 请登录后投票
时间:2006-09-27
cookoo 写道
bizzare是Module的类方法啊,不是实例方法

引用
一个ruby对象obj,要想obj.respond_to?(:method)为真,必须obj.class.instance_methods.index("method")不是nil。

这句话只在obj是实例对象时才成立:
Rubbish.respond_to? :kick #=>true
Rubbish.class.instance_methods.include? :kick #=> false ,类的类等于Class 
Rubbish.methods.include? :kick #=> true



不能用include? :kick,而必须用include? "kick"
   
0 请登录后投票
时间:2006-09-27
Rubbish.ancestors #=> [Rubbish, Object, Kernel]
Module不是它的父类,当然不会继承bizzare2
   
0 请登录后投票
时间:2006-09-27
555 统一用string不用symbol了,有些方法不会自动转的
   
0 请登录后投票
论坛首页 Ruby版

跳转论坛: