[Ruby] Modules

1. Namespace:

Ruby可以像Javascript一样定义全局的functions。这些functions都放在global namespace中。容易和之后的method name冲突。我们可以用module来包括这些functions。

1. module中的方法需要加self:

def self.good_name
end

2. 调用的时候先需要引入module文件: if they are not in the same file!!

require 'image_utils'

3. 调用方法:

ImageUtils.preview(image)

Code:

#image_utils.rb

module ImageUtils
    def self.preview(image)
    end

    def self.transfer(image, destination)
    end
end


#run.rb

require 'image_utils'

image = user.image
ImageUtils.preview(image)

 

2. Mixin

另一种方法是Mixin, 我们需要做的是把Module在class中include。然后就可以作为class instance的方法调用。

#image_utils.rb

module ImageUtils
    def preview
    end

    def transfer(destination)
    end
end

#avatar.rb
require 'image_utils' #require module file

class Image
    include ImageUtils   #including module
end

#run.rb

imge = user.image
image.preview

 

Ancestors:

被加载进去的模块会被加入到Image的ancestor(祖先)中去,可以用:

Image.ancestors
    [Image, ImageUtils, Object, Kernel, BasicObject]


Image.include_modules
    [ImageUtils, Kernel]

 

Mixins vs Class inheritance:

Class inheritance: 

Ruby中一个class只能继承一个父类,所以如何几个class的behaviors不适合的话最好不要用继承。

Mixing:

以上的情况适用Mixin更加的合适。

 

另外Mixin同时可以include多个Modules:

 

 

Mixin -- Extend:

Mixin还有另外一种形式:extend。

include: 把module的方法用class instance来调用。

extend: 把module的方法当做class methods来调用,可以理解为静态方法。

module Searchable
    def find_all_from(user)
    end
end


class Tweet
    extend Searchable
end


Tweet.find_all_from('@GreggPollack')

 

 

Object extend a module:

If an object extends a module, the module only avaiable for this object.

 

 

Hooks -- Self.included

If we want to both include and extends modules in the same class. It is also possible.

The extended Module should inside the included module.

This is how it looks like:

 

Also, we can make it better by using Hooks: it will still work as the same.

module ImageUtils
    def self.included(base)
        base.extend(classMethodsModule)
    end

    module classMethodsModule
    end
end

 

 

self.included()

is a special “callback” method that gets automatically called when ever the module is included into something.

 

ActiveSupport::concern

Read More: 

http://www.fakingfantastic.com/2010/09/20/concerning-yourself-with-active-support-concern/

http://api.rubyonrails.org/classes/ActiveSupport/Concern.html

 

 

1. ActiveSupport::concern will help to handle the dependencies. 

2. So by using ActiveSupport:concern can remove the code:

self.included(base)
    base.extend(ClassMethods)
end

3. in inlcuded do block can call the method in in-side Module:

module LibraryUtils

  extend ActiveSupport::Concern
  included do
    load_game_list 
  end
  
  def add_game(game)
  end

  def remove_game(game)
  end

  module ClassMethods
    def search_by_game_name(name)
    end

    def load_game_list
    end
  end
end

Example:

require 'active_support/concern'
module LibraryLoader

  extend ActiveSupport::Concern

  module ClassMethods
    def load_game_list
    end
  end
end

module LibraryUtils
  extend ActiveSupport::Concern
  include LibraryLoader
  included do
    load_game_list
  end
end

class AtariLibrary
  include LibraryUtils
end

 

posted @ 2014-09-27 01:46  Zhentiw  阅读(218)  评论(0)    收藏  举报