Ruby,如何在同一方法中获取方法的整个命名空间定义路径?
Ruby, How I can obtain the whole namespace definition path for a method inside the same method?
如何在同一方法中获取方法的整个命名空间定义路径?
使用这个例子来简化问题:
module Parent
module Child
def self.get_complete_namespace
this_path = ???
puts this_path.to_s
end
end
end
Parent::Child.get_complete_namespace
#=> "Parent::Child.get_complete_namespace"
所以要放置或打印出这个字符串“Parent::Child.get_complete_namespace”,使用 self super o 之类的东西的“this_path”变量值是多少?
我不知道有任何现成的功能,但您可以使用 __callee__
(或 __method__
)
轻松创建一个
module Parent
module Child
def self.get_complete_namespace
m = method(__callee__)
"#{m.receiver.name}.#{m.name}"
end
end
end
Parent::Child.get_complete_namespace
#=> "Parent::Child.get_complete_namespace"
一些使用说明:
__callee__
和__method__
通常会return相同的符号。如果该方法是别名,则 __callee__
return 是被调用的方法名称,而 __method__
将 return 定义的方法名称。
- 对于class/module方法,您需要使用
m.receiver
。对于实例方法,您需要使用 m.owner
。参见 Method。
Class 示例:
module Parent
class Child
def self.get_complete_namespace
m = method(__callee__)
"#{m.receiver.name}.#{m.name}"
end
def get_complete_namespace
m = method(__callee__)
"#{m.owner.name}.#{m.name}"
end
alias_method :complete, :get_complete_namespace
end
end
Parent::Child.get_complete_namespace
#=> "Parent::Child.get_complete_namespace"
Parent::Child.new.get_complete_namespace
#=> "Parent::Child.get_complete_namespace"
Parent::Child.new.complete
#=> "Parent::Child.complete"
编辑 - one-liner 版本:
def self.get_complete_namespace
method(__callee__).instance_eval { "#{receiver.name}.#{name}" }
end
可以这样写get_complete_namespace
module Grandparent
module Parent
module Child
def self.get_complete_namespace
"#{Module.nesting.first}::#{__method__}"
end
end
end
end
Grandparent::Parent::Child.get_complete_namespace
#=> "Grandparent::Parent::Child.get_complete_namespace"
见Module::nesting and Kernel#method。
方法Grandparent::Parent::Child::get_complete_namespace
的操作线是否
Module.nesting
该方法会返回
[Grandparent::Parent::Child, Grandparent::Parent, Grandparent]
如何在同一方法中获取方法的整个命名空间定义路径?
使用这个例子来简化问题:
module Parent
module Child
def self.get_complete_namespace
this_path = ???
puts this_path.to_s
end
end
end
Parent::Child.get_complete_namespace
#=> "Parent::Child.get_complete_namespace"
所以要放置或打印出这个字符串“Parent::Child.get_complete_namespace”,使用 self super o 之类的东西的“this_path”变量值是多少?
我不知道有任何现成的功能,但您可以使用 __callee__
(或 __method__
)
module Parent
module Child
def self.get_complete_namespace
m = method(__callee__)
"#{m.receiver.name}.#{m.name}"
end
end
end
Parent::Child.get_complete_namespace
#=> "Parent::Child.get_complete_namespace"
一些使用说明:
__callee__
和__method__
通常会return相同的符号。如果该方法是别名,则__callee__
return 是被调用的方法名称,而__method__
将 return 定义的方法名称。- 对于class/module方法,您需要使用
m.receiver
。对于实例方法,您需要使用m.owner
。参见 Method。
Class 示例:
module Parent
class Child
def self.get_complete_namespace
m = method(__callee__)
"#{m.receiver.name}.#{m.name}"
end
def get_complete_namespace
m = method(__callee__)
"#{m.owner.name}.#{m.name}"
end
alias_method :complete, :get_complete_namespace
end
end
Parent::Child.get_complete_namespace
#=> "Parent::Child.get_complete_namespace"
Parent::Child.new.get_complete_namespace
#=> "Parent::Child.get_complete_namespace"
Parent::Child.new.complete
#=> "Parent::Child.complete"
编辑 - one-liner 版本:
def self.get_complete_namespace
method(__callee__).instance_eval { "#{receiver.name}.#{name}" }
end
可以这样写get_complete_namespace
module Grandparent
module Parent
module Child
def self.get_complete_namespace
"#{Module.nesting.first}::#{__method__}"
end
end
end
end
Grandparent::Parent::Child.get_complete_namespace
#=> "Grandparent::Parent::Child.get_complete_namespace"
见Module::nesting and Kernel#method。
方法Grandparent::Parent::Child::get_complete_namespace
的操作线是否
Module.nesting
该方法会返回
[Grandparent::Parent::Child, Grandparent::Parent, Grandparent]