我有一个带有一些方法的类。这是 super secret ,但我已经在这里复制了我能复制的内容。
Class RayGun
# flashes red light
# requires confirmation
# makes "zowowowowowow" sound
def stun!
# ...
end
# flashes blue light
# does not require confirmation
# makes "trrrtrtrtrrtrtrtrtrtrtr" sound
def freeze!
# ...
end
# doesn't flash any lights
# does not require confirmation
# makes Windows startup sound
def killoblast!
# ...
end
end
我希望能够在运行时询问类有关其中一种方法的信息并接收散列或结构,如下所示:
{:lights => 'red', :confirmation => false, :sound => 'windows'}
执行此操作的最佳方法是什么?显然,您可以同时拥有单独的 YAML 文件并设置一个约定来将两者关联起来,但理想情况下我希望代码和元数据位于一处。
我能想到的最有前途的想法是这样的:
class RayGun
cattr_accessor :metadata
def self.register_method(hsh)
define_method(hsh.name, hsh.block)
metadata[hsh[:name]] = hsh
end
register_method({
:name => 'stun!',
:lights => 'red',
:confirmation => 'true',
:sound => 'zowowo',
:block => Proc.new do
# code goes here
})
# etc.
end
有人有更好的想法吗?我是不是在吠叫一棵非常错误的树?
最佳答案
我发现了另一个策略 http://github.com/wycats/thor/tree 。 Thor 让你可以写这样的东西:
Class RayGun < Thor
desc "Flashes red light and makes zowowowowow sound"
method_options :confirmation => :required
def stun!
# ...
end
end
它通过使用(未记录的)钩子(Hook)Module#method_added
来管理它。它的工作原理如下:
调用
Thor#desc
并Thor#method_options
设置实例 变量@desc,@method_options
。定义方法
stun!
调用雷神#method_add(meth)
Thor#method_added
寄存器Task.new(meth.to_s, @desc, @method_options)
(粗略地说) 并取消设置@desc
,@method_options
。现在已准备好执行下一个方法
整洁!太简洁了,我要接受我自己的答案:)
关于ruby - 在运行时获取/设置 Ruby 方法元数据的最佳策略是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/443152/