I need to define the constant in the module that use the method from the class that includes this module:
我需要在模块中定义使用包含此模块的类中的方法的常量:
module B
def self.included(base)
class << base
CONST = self.find
end
end
end
class A
def self.find
"AAA"
end
include B
end
puts A::CONST
But the compiler gives the error on the 4th line.
但是编译器在第4行给出了错误。
Is there any other way to define the constant?
有没有其他方法来定义常量?
3 个解决方案
#1
The more idiomatic way to achieve this in Ruby is:
在Ruby中实现这一点的更惯用的方法是:
module B
def self.included(klass)
klass.class_eval <<-ruby_eval
CONST = find
ruby_eval
# note that the block form of class_eval won't work
# because you can't assign a constant inside a method
end
end
class A
def self.find
"AAA"
end
include B
end
puts A::CONST
What you were doing (class << base) actually puts you into the context of A's metaclass
, not A itself. The find
method is on A itself, not its metaclass. The thing to keep in mind is that classes are themselves objects, and so have their own metaclasses.
你正在做什么(类<< base)实际上会让你进入A的元类的上下文,而不是A本身。 find方法在A本身,而不是它的元类。要记住的是,类本身就是对象,因此有自己的元类。
To try to make it clearer:
试图让它更清晰:
class Human
def parent
# this method is on the Human class and available
# to all instances of Human.
end
class << self
def build
# this method is on the Human metaclass, and
# available to its instance, Human itself.
end
# the "self" here is Human's metaclass, so build
# cannot be called.
end
def self.build
# exactly the same as the above
end
build # the "self" here is Human itself, so build can
# be called
end
Not sure if that helps, but if you don't understand it, you can still use the class_eval idiom above.
不确定这是否有帮助,但如果你不理解它,你仍然可以使用上面的class_eval习语。
#2
In your specific case.
在你的具体情况下。
module B
def self.included(base)
base.const_set("CONST", base.find)
end
end
class A
def self.find
"AAA"
end
include B
end
puts A::CONST
Despite it works, it's a little bit messy. Are you sure you can't follow a different way to achieve your goal?
尽管它有效,但它有点乱。您确定不能以不同的方式实现目标吗?
#3
module B
def self.included(base)
class << base
CONST = self.find
end
end
end
class A
class << self
def self.find
"AAA"
end
end
include B
end
then the compiler error is fixed, pls try.
那么编译错误是固定的,请试试。
#1
The more idiomatic way to achieve this in Ruby is:
在Ruby中实现这一点的更惯用的方法是:
module B
def self.included(klass)
klass.class_eval <<-ruby_eval
CONST = find
ruby_eval
# note that the block form of class_eval won't work
# because you can't assign a constant inside a method
end
end
class A
def self.find
"AAA"
end
include B
end
puts A::CONST
What you were doing (class << base) actually puts you into the context of A's metaclass
, not A itself. The find
method is on A itself, not its metaclass. The thing to keep in mind is that classes are themselves objects, and so have their own metaclasses.
你正在做什么(类<< base)实际上会让你进入A的元类的上下文,而不是A本身。 find方法在A本身,而不是它的元类。要记住的是,类本身就是对象,因此有自己的元类。
To try to make it clearer:
试图让它更清晰:
class Human
def parent
# this method is on the Human class and available
# to all instances of Human.
end
class << self
def build
# this method is on the Human metaclass, and
# available to its instance, Human itself.
end
# the "self" here is Human's metaclass, so build
# cannot be called.
end
def self.build
# exactly the same as the above
end
build # the "self" here is Human itself, so build can
# be called
end
Not sure if that helps, but if you don't understand it, you can still use the class_eval idiom above.
不确定这是否有帮助,但如果你不理解它,你仍然可以使用上面的class_eval习语。
#2
In your specific case.
在你的具体情况下。
module B
def self.included(base)
base.const_set("CONST", base.find)
end
end
class A
def self.find
"AAA"
end
include B
end
puts A::CONST
Despite it works, it's a little bit messy. Are you sure you can't follow a different way to achieve your goal?
尽管它有效,但它有点乱。您确定不能以不同的方式实现目标吗?
#3
module B
def self.included(base)
class << base
CONST = self.find
end
end
end
class A
class << self
def self.find
"AAA"
end
end
include B
end
then the compiler error is fixed, pls try.
那么编译错误是固定的,请试试。