开发者

Are modules in ruby only meant to be used when multiple objects require its functionality?

I've read that the main service provided by a module is to contain and group similar functions that are needed by several objects. But is 开发者_如何转开发it a good practice to create a module for something like a parser even if you are certain that only one object will ever require its services?


Modules serve two purposes. The first as you have noted is to allow functionality to be added to a diverse set of classes (diverse meaning outside the inheritance tree). The second an by far more common use is to organize the names space. When you see code like ActiveRecord::Base or BSON::ObjectID the authors of these gems have placed their functionality in a module, ActiveRecord and BSON respectively, that prevents their class names from conflicting with the applications they are included in or other libraries.

With the parser you mentioned, it sounds to me like you want to construct a singleton class rather then a module.


It can help for organization to create a module even if you are using it in one place. For example you might have a lot of methods that are all related, but not really related to the code you are including the module in. This is similar to the the organization that a class provides, except that a module isn't focused on an object.


main service provided by a module is to contain and group similar functions that are needed by several objects

I would re-word it to "group similar functions that might be needed by at least one object". It's very frequent that you don't know how many classes will end up including or extending a module (for example if you are writing a library)

Independently of that, I see two more "main purposes":

  • They are a way to provide scopes (you can package several classes and other modules inside one module).
  • They have a callback called included. This might seem trivial, but that callback is key in a lot of interesting meta-programming techniques.


I would go for a class (if you got not too much code). Place it under /lib

class Parse
  def self.xml(xml_string)
    ...
  end
end

Parse.xml("<xml></xml>")
  1. You can call it from anywhere.
  2. http://en.wikipedia.org/wiki/Separation_of_concerns

Modules are indeed a group of similar functions. If you got a lot of parsing code you could do:

class Xml
  acts_as_parser
end

class Json
  acts_as_parser
end

...

acts_as_parser will load the group of functions from the module.


But is it a good practice to create a module for something like a parser even if you are certain that only one object will ever require its services?

Yes.

In Ruby, modules help a whole lot with separation of concerns and are very good for doing "aspect-oriented" programming (i.e., fun with mixins).

# Basic Hierarchy
class X
  def say ; 'X' end
end
class Y < X
  def say ; super + 'Y' end
end
y = Y.new
y.say #=> 'XY'

# Throwing in an aspects/mixins
module A
  def say ; super + 'A' end
end
class Y
  include A
end
y.say #=> 'XAY'

# Throwing in another aspects/mixins
module B
  def say ; super + 'B' end
end
class Y
  include B
end
y.say #=> 'XABY'


When faced with an excessively large class, sometimes I split it up into a couple of modules based on its functionality, and have a virtually empty class just include those modules.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜