这是我的代码:
module X
class << self
def x() %s(hi5) end
end
def y() rand(65..122).chr end
end
class Object
include X
# Here I want class Object to have x() from the X module.
end
puts y # => A random character from ('A'..'z')
# puts x
我想以与致电x
相同的方式致电y
。我可以这样做吗?
答案 0 :(得分:2)
如果您以与定义x
相同的方式定义y
,则可以。 class << self
部分仅使x
成为模块方法,不能与include
一起添加。因此要解决:
module X
def x
%s(hi5)
end
def y
rand(65..122).chr
end
def self.z
:nope
end
end
class Object
include X
end
puts x
puts y
puts z # Error, as this can't be included
此处使用z
声明方法添加了self.z
,它比class << self
少了很多麻烦,但效果相同。
请注意,不带参数的Ruby方法的括号被省略。您还应该用换行符分隔方法定义和主体。
答案 1 :(得分:2)
您似乎想要做的是包括新的实例方法,同时用新的类方法扩展您的类。以下是基于PICK AX的书:
module X
module ClassMethods
def x()
puts "In class"
end
end
def y()
puts "In instance"
end
def self.included(host_class)
host_class.extend(ClassMethods)
end
end
class Object
include X
end
现在
# Test the instance method
Object.new.y # Prints "In instance"
# Test the class method
Object.x # Prints "In class"
答案 2 :(得分:1)
尽管在实践中不太可能看到这种情况,但您可以按照以下步骤进行操作。
module X
def self.x
:hi5
end
def self.v(str)
str.capitalize
end
def self.z(str)
yield(str)
end
def y
:ho
end
end
X.x
#=> :hi5
X.v("cat")
#=> "Cat"
X.z("cat") { |s| s.upcase }
#=> "CAT"
class Object
include X
X.methods(false).each do |m|
define_method(m) { |*args, &block|
X.method(m).call(*args, &block) }
end
end
#=> [:v, :x, :z]
Object.instance_methods && [:x, :v, :z, :y]
#=> [:x, :v, :z, :y]
o = Object.new
o.x
#=> :hi5
o.v("cat")
#=> "Cat"
o.z("cat") { |s| s.upcase }
#=> "CAT"
o.y
#=> :ho
这也可以。
x #=> :hi5
v("cat")
#=> "Cat"
z("cat") { |s| s.upcase }
#=> "CAT"
y #=> "m"
为什么?因为x
与self.x
(self #=> main
)和
self.is_a? Object
#=> true
注意
module X
def self.m
#...
end
end
是
的简写module X
class << self
def m
#...
end
end
end