ruby元编程(1)

面试中碰到一些面试官提到的关于ruby元编程的问题的总结

  • class和module的区别
  1. 官方说明
    1. class doc 类是第一类型(first-class)的对象,每一个类都是Class类的对象。
    2. module doc 模块(Module)是方法和常量的集合。方法可以是实例方法也可以是模块方法,当一个模块被include到一个类中时,实例方法会出现在该类中,而模块方法是不会出现的。
module Mod
  def one
    "This is one"
  end
  module_function :one
end

class Cls
  include Mod
  def call_one
    one
  end
end

Mod.one     #=> "This is one"
c = Cls.new
c.call_one  #=> "This is one"

module Mod
  def one
    "This is the new one"
  end
end

Mod.one     #=> "This is one"
c.call_one  #=> "This is the new one"
  1. extend & include & prepend
module A
  def t
    puts "t method in A"
  end
end

class B
  include A
end

class C
  extend A
end

B将新增一个实例方法t,C将新增一个类方法t,同时,B的祖先链ancestors中将增加A,而C的祖先链中没有A。

module A
  def t
    puts "in A"
  end
end

class B
  include A
  def t
    puts "in B"
  end
end

class C
  prepend A
  def t
    puts "in C"
  end
end

B.new.t   #输出 ‘in B’
C.new.t   #输出 ‘in A’

puts B.ancestors
puts C.ancestors

输出如下图所示:

inheritance diagram

prependinclude类似,首先都是添加实例方法的,不同的是扩展module在祖先链上的放置位置不同。

  1. ruby类的继承关系
继承关系图

所有类的基类

BasicObject

类的类与超类

Metaprogramming Ruby 2
  1. 方法如何调用
    1. 实例方法,首先在实例中找,然后在实例对象的单件类中找,之后沿祖先链依次向上找
    2. 类方法,首先在类的单件类中找,然后沿着类的单件类的祖先链依次向上找(类的单件类的祖先链 = 类的祖先链的各个节点的单件类组成的链)
  • instance_eval & class_eval
class A
  def t1
    p "t1"
  end
end
obj1 = A.new

def obj1.t0
  p "t0"
end

class << obj1
  def t2
    p "t2"
  end
end

class << A
  def t3
    p "t3"
  end
end

obj1.instance_eval %{
  def t4
    p "t4"
  end

  def self.t5
    p "t5"
  end
}

A.instance_eval %{  
  def t6
    p "t6"
  end
}

A.class_eval %{  
  def t7
    p "t7"
  end
}

obj1.singleton_class.send(:define_method, :t8){p 't8'}

obj1.class.send(:define_method, :t9){p 't9'}

A.singleton_class.send(:define_method, :t10){p '10'}

各自拥有的方法如下图所示:

methods

参考文章

动态添加对象方法
动态添加类方法
ruby include extend prepend 使用方法

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • ruby面向对象初步理解 类与对象无疑是ruby的核心,可能最开始看上去有一点困惑,似乎有太多的概念:类、对象、类...
    感觉被掏空阅读 1,196评论 0 3
  • 对象模型 所有class定义之外的代码默认运行在顶级对象main中。 打开类 ruby的class更像是一个作用于...
    五月的约修亚阅读 3,497评论 0 4
  • 最近复习了下 ruby 对象模型的知识,参照了 Ruby Metaprogramming,于是边看边做笔记,还是收...
    张羽辰阅读 539评论 0 4
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,868评论 18 139
  • 你有多久没写过一篇文章了?我的上一篇文章是我的高考作文,所以是有多久没有写过东西了。今天突然想写一写自己的第一次...
    GaoBiGe阅读 521评论 0 0