avatar

Derek Zeng

Loneliness is the gift of life

吐槽 ruby module

其实ruby真的不容易学,因为它有太多非主流的东西了。今天我就来说说 ruby module.

ruby module 的主要用途无非就是给function 分类,给其一个命名空间。 比如

module M
  def self.hello
    puts 'world'
  end
end
module N
  def self.hello
    puts '世界'
  end
end
M::hello # world
N::hello # 世界

这很好理解。但从python过来的我觉得比起python这样真的太麻烦了。在python里,文件名自己就组成了一个命名空间,所以根本不需要有像module这样的东西。另外声明一个class也起到了也起到了命名空间的作用,因为class 静态方法都是有自己的命名空间的。这个在主流OOP语言里都是一样的。python 甚至不需要::来访问静态方法。

# python3
class N:
  @staticmethod
  def hello():
    return 'world'

print(N.hello()) # world

当然另一个module的作用就是mixin。其实这个比起python真的真的搞得太复杂了。首先ruby 需要一个新的关键词include来mix module in。其次,module 里的方法本身还需要分清楚谁是mixin方法,谁不是。上面那个module的例子里我用了self.hello来定义一个module method。如果是mixin method则不能在self(也就是module object自己)上定义。哇,真的很麻烦。 在python里面,mixin就是一个独立的class。不需要include因为class extend就行了,这个在大部分OOP语言里都是一样的。自然而然,多继承的class把父类写在一起就行,何必搞一个include 呢。

class Mother:
  def greet(self):
    return 'mother'

class Father:
  def greet(self):
    return 'father'

class Me(Mother, Father):
  pass

不只是include ruby还搞了个extend module来让这件事情变得更有趣。不得不佩服,设计这个的人头脑真的很活跃。可能也是为什么你在ruby里总可以找到一百种方法来做同一件事情,然后每个人的preference又不一样,写的爽就行了。

一个例子就可以看出ruby 的语法有多奇葩:

module JSONAPI
  module Serializable
    class Resource
      module DSL
        def self.extended(klass)
          class << klass
...

ref: http://ruby-doc.com/docs/ProgrammingRuby/html/tut_modules.html

(End of article)