首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Ruby 中的模块

今天我们来讲讲 Ruby 里面的模块是怎么工作的!

模块在 Ruby 里面非常重要。我们知道,在 Ruby 中,是不能直接使用多继承的,而使用了一种 mixin 的机制来实现多继承的需求。模块就是 mixin 的载体。

模块同类一样,也有 class method 和 instance method。其中 class method 在模块中称为模块方法,是可以直接调用的。

module Foo

def self.hello

puts 'hello world!'

end

end

Foo.hello #=> 'hello world!'

而对于模块里面的 instance method, 主要有两种形式,而这取决于如何包含这个模块: include 还是 extend 。

module Foo

def awesome

puts 'awesome method'

end

end

class Car1

include Foo

end

class Car2

extend Foo

end

Car1.new.awesome #=> 'awesome method'

Car2.awesome #=> 'awesome method'

ok。看上去非常不错。可是,我现在有一个非常好用的模块,我希望包含这个模块后,有些方法作为实例方法,有些方法作为类方法,这时候,该如何做呢?

道高一尺,魔高一丈。你可以这样:

module Foo

def self.included(base)

base.extend ClassMethods

end

module ClassMethods

def cawesome

puts "hello, i'm class method"

end

end

def awesome

puts "hello, i'm instance method"

end

end

class Car

include Foo

end

Car.new.awesome #=> "hello, i'm instance method"

Car.cawesome #=> "hello, i'm instance method"

So Beautiful. 这看上去非常不错。

但是,问题又来了,假如我们有另一个模块,依赖于 Foo 模块,像这样:

module Bar

include Foo

def self.included(base)

base.cawesome

end

end

class Car

include Bar

end

Car.cawesome #=> NoMethodError

出问题了,为什么 Car 中没有 cawesome 这个方法?

因为 included 是 module 的一个方法,所以 Bar 在包含 Foo 这个模块时,直接将 cawesome 变成了 Bar 的模块方法。所以在包含 Bar 时,在 Car 上面调用 cawesome 就报错了。

然后,那我们直接在 Car 里面包含 Foo 和 Bar。像这样:

module Bar

def self.included(base)

base.cawesome

end

end

class Car

include Foo

include Bar

end

Car.cawesome #=> "hello, i'm class method"

ok, 看上去不错。

可是你是一个代码偏执狂:为什么 Bar 的依赖要 Car 来处理呢?

如果你想知道怎么做,可以看下一篇文章 ActiveSupport::Concern 使用及源码解析。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20200112A0HRMB00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券