- xml - AJAX/Jquery XML 解析
- 具有多重继承的 XML 模式
- .net - 枚举序列化 Json 与 XML
- XML 简单类型、简单内容、复杂类型、复杂内容
我正在寻找确保我的对象中定义的一组方法都调用特定方法的方法。为了说明,假设我有对象 A 和 B,它们都有如下方法:
class A
def method_a
important_method!
end
end
class B
def method_b
important_method!
end
end
我如何轻松确保来自 A 的 method_a
和 method_b
都调用了 important_method!
?
在这种情况下,important_method
将来自一个模块,该模块将包含在 A 和 B 中(实际上在它们的公共(public)父类(super class)中)。
到目前为止,我尝试的是将两个对象包装在定义 method_missing
和收集方法调用的代理中,但这只告诉我 method_a
和 method_b
被调用。有任何想法吗?
最佳答案
我的答案最初是使用 TracePoint
,但后来我读到 @user2074840 如何使用 alias
,这让我想到了使用 alias
与 caller
结合,这导致了一个非常直接的解决方案。我在下面将其呈现为 #2 Use Caller
。
#1 使用 TracePoint
在 Ruby 2.0+ 中你可以使用 TracePoint获取您需要的信息。 (在早期版本中,您可以使用 Kernel#set_trace_point 。)
为了了解这是如何工作的,让我们写一些示例代码:
def a
puts "a"
c
important
end
def b
puts "b"
important
end
def c
puts "c"
end
def important
puts "important"
end
我们现在设置跟踪,指定两个感兴趣的事件,:call
和 :return
,以及我们要保存的信息,事件 (:call
or :return
) 和方法 (:a
, :b
or :c
):
events = []
trace = TracePoint.trace(:call, :return) { |tp|
events << { event: tp.event, method: tp.method_id } }
然后执行代码:
4.times { send([:a, :b, :c][rand(0..2)]) }
# b
# important
# b
# important
# a
# c
# important
# c
禁用跟踪:
trace.disable
并检查收集到的信息:
p events
# [{:event=>:call, :method=>:b},
# {:event=>:call, :method=>:important},
# {:event=>:return, :method=>:important},
# {:event=>:return, :method=>:b},
# {:event=>:call, :method=>:b},
# {:event=>:call, :method=>:important},
# {:event=>:return, :method=>:important},
# {:event=>:return, :method=>:b},
# {:event=>:call, :method=>:a},
# {:event=>:call, :method=>:c},
# {:event=>:return, :method=>:c},
# {:event=>:call, :method=>:important},
# {:event=>:return, :method=>:important},
# {:event=>:return, :method=>:a},
# {:event=>:call, :method=>:c},
# {:event=>:return, :method=>:c}]
请注意,这不能在 IRB
或 PRY
中运行。
我们现在可以提取对 :important
的调用,如下所示:
def calls_to_method(events, method)
stack = []
events.each_with_object([]) do |h, calling_methods|
stack << h
while stack.size > 1 &&
stack[-1][:event] == :return &&
stack[-2][:event] == :call &&
stack[-1][:method] == stack[-2][:method] do
if (stack.size > 2 && (stack[-1][:method] == method))
calling_methods << stack[-3][:method]
end
stack.pop
stack.pop
end
end
end
calls = calls_to_method(events, :important)
#=> [:b, :b, :a]
calls.uniq
#=> [:b, :a]
#2 使用来电
此方法使用 alias
和 Kernel#caller :
@calling_methods = []
alias :old_important :important
def important
@calling_methods << caller.first[/`(.*)'/,1]
old_important
end
4.times { send([:a, :b, :c][rand(0..2)]) }
# b
# important
# c
# a
# c
# important
# a
# c
# important
# b
# a
# a
p @calling_methods
#=> ["b", "a", "a"]
这是 caller
返回的数组示例:
caller
#=> ["abc.rb:9:in `b'",
# "abc.rb:32:in `block in <main>'",
# "abc.rb:32:in `times'",
# "abc.rb:32:in `<main>'"]
这只是我们使用的第一个元素:
caller.first
#=> "abc.rb:9:in `b'",
我们应用正则表达式来提取方法名称,方法名称前面是 '
'` (Ascii 96),后面是单引号。
关于Ruby - 捕获从方法体发送的方法调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28591480/
程序集,masm 嘿,我写了宏来打印存储在 dane1 段中的 1 字节值。 我将值除以 16,然后将提醒推送到堆栈,直到值==0。然后我弹出提醒将它们转换为 ASCII 码,并打印它们。 有人可以看
我在 Apache Geronimo 2.1.3 上有一个 Web 服务应用程序。 我正在使用 JAX-WS,使用 SOAP 1.1 注释 POJOS。 (使用 Sun JDK 1.5) 各种客户端都
我有一个数据变量,monthArray,它被多个消费者读取,并由单个定期更新程序线程定期更新数据。全部异步。 我已经考虑了这两个选项来安全地执行更新。 ArrayList tempArray
我有一组 3D 体。每个 Body 由 8 个点定义,每个点具有三个坐标。所有的物体都是立方体的或近似立方体的。我想用系统的点栅格“填充”立方体。坐标存储在简单的 data.frames 中。 我开发
我正在处理遗留代码,需要打补丁。 问题:一个古老的应用程序发送错误的 HTTP POST 请求。其中一个参数未经过 URL 编码。我知道这个参数总是排在最后而且我知道它的名字。我现在正尝试在运行在 t
我想在触摸屏幕时移动 sprite body ,但它不能发生...... -(void)ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event
这个问题在这里已经有了答案: Can a union be initialized in the declaration? (3 个答案) 关闭 7 年前。 如果它是一个struct那么它就可以完成
我正在尝试获取生成 sigsys 信号的系统调用的地址!但我从 gcc 收到以下错误: gcc emulator.c -fms-extensions error: ‘siginfo_t’ has no
当我使用 Postman 进行 API 调用时,我收到一个 JSON 对象..这是我所期望的。 但是,当我像这样与 Guzzle 进行相同的调用时: $client = new \GuzzleHttp
在编码时,出现了差异。通常在编写简单的方法或构造函数时,我经常使用表达式体技术。但是,当我产生以下内容时: public class Sample : ISample { private r
我正在使用 LibGDX 创建一个新项目。 我想做的是,我将 tmx 文件中的主体加载到工作正常的关卡中。尸体也有一个 Sprite 。 问题是,我想让用户触摸场景中的某些 body 。当他们触摸 b
我的意图:在不使用 union 的情况下循环遍历一个结构的 30 个成员,所有成员都是字符数组类型,每个成员都存储对 itoa 的调用结果。在下面的代码中,我将结构体成员命名为a-z、A-D。在调用函
我必须将我的代码段之一从 C 转换为 java。代码如下。 union commandString{ char commndStr[20]; struct{ char
#include union NumericType { float value; int intvalue; }Values; int main() { Values.va
我在此代码中收到错误: fun num(num:Int):Int { if (num > 0){ print(num % 10) return num / 10
我是一名优秀的程序员,十分优秀!