我试图理解来自github repo的代码.它是设置客户端的gem的主要模块.
module Github
# more code
class << self
def included(base)
base.extend ClassMethods # what would this be for?
end
def new(options = {}, &block)
Client.new(options, &block)
end
def method_missing(method_name, *args, &block)
if new.respond_to?(method_name)
new.send(method_name, *args, &block)
elsif configuration.respond_to?(method_name)
Github.configuration.send(method_name, *args, &block)
else
super
end
end
def respond_to?(method_name, include_private = false)
new.respond_to?(method_name, include_private) ||
configuration.respond_to?(method_name) ||
super(method_name, include_private)
end
end
module ClassMethods
def require_all(prefix, *libs)
libs.each do |lib|
require "#{File.join(prefix, lib)}"
end
end
# more methods ...
end
extend ClassMethods
require_all LIBDIR,
'authorization',
'validations',
'normalizer',
'parameter_filter',
'api',
'client',
'pagination',
'request',
'response',
'response_wrapper',
'error',
'mime_type',
'page_links',
'paged_request',
'page_iterator',
'params_hash'
end
Run Code Online (Sandbox Code Playgroud)
class << self
和module ClassMethods
使用,再延伸,而不是包含在class << self
一部分?def included(base)
.这似乎将类方法添加到特定对象中.为什么会这样?它可能与课程的功能有关,但我不明白.art*_*pov 15
module MyModule
class << self
def included(base)
base.extend ClassMethods # what would this be for?
end
<...>
end
<...>
end
Run Code Online (Sandbox Code Playgroud)
这实际上是Ruby中非常常见的做法.基本上,它所说的是:当某个对象执行时include MyModule
,也可以使用它extend MyModule::ClassMethods
.如果你想要一个mixin,它不仅可以为类的实例添加一些方法,而且可以添加到类本身,那么这样的专长很有用.
一个简短的例子:
module M
# A normal instance method
def mul
@x * @y
end
module ClassMethods
# A class method
def factory(x)
new(x, 2 * x)
end
end
def self.included(base)
base.extend ClassMethods
end
end
class P
include M
def initialize(x, y)
@x = x
@y = y
end
def sum
@x + @y
end
end
p1 = P.new(5, 15)
puts "#{p1.sum} #{p1.mul}"
# Calling the class method from the module here!
p2 = P.factory(10)
puts "#{p2.sum} #{p2.mul}"
Run Code Online (Sandbox Code Playgroud)