Ruby:定义使用语法糖的方法时的奇怪行为
Ruby: Strange behaviour when defining methods that utilize syntax sugar
目前正在研究一些元编程的想法,先介绍一下:
我可以将 class
或 module
中的字符串 'template' 定义为 Constant
并在以后像这样使用它:
class Test1
ConstString = %(the string in here is %{instring})
end
puts Test1::ConstString % { instring: "test" }
#=> the string in here is test
问题是
一个。基于基准测试,仅仅定义一个函数可以做同样的事情快 3 倍(基准是 1000000.times):
user system total real
Constant: 1.080000 0.000000 1.080000 ( 1.087187)
Function: 0.350000 0.000000 0.350000 ( 0.346578)
b。我想将它们与常规函数分开,因为我想如何使用它们。
所以我决定创建一个新的 class 来继承 Proc...
并包含一个 module
以投入 Percent/Modulo 语法。
module ProcPercentSyntax
def %(*args)
self.call(*args)
end
end
class TestFromProc < Proc
include ProcPercentSyntax
end
class Test2
ConstString = TestFromProc.new { |x, y| %(this is a string with #{x} and #{y}) }
end
这样我就可以这么叫了!
puts Test2::ConstString % "test", "test2"
但是...
#=> this is a string with test and
令人不安的是没有抛出任何错误。
为了确保这不是另一个问题,我继续这样做了:
module ProcNotPercentSyntax
def make(*args)
self.call(*args)
end
end
class TestFromProc < Proc
include ProcNotPercentSyntax
end
puts Test2::ConstString.make "test", "test2"
还有...
#=> this is a string with test and test2
请原谅这个问题的零星性质,我将这样总结我的意图:
Why does the method seem to miss out on the second given parameter when using %
as a method name?
puts Test2::ConstString % "test", "test2"
But...
#=> this is a string with test and
不是,那是不是的结果。结果是:
# this is a string with test and
# test2
#=> nil
Disconcertingly without any error thrown.
为什么会出现错误?用两个参数调用 puts
是完全合法的,这就是你在这里所做的。你会期待什么
puts 1+1, 3
打印?完全一样!
Why does the method seem to miss out on the second given parameter when using %
as a method name?
%
是一个 二元 运算符,类似于 <<
或 |
。它只需要两个个操作数,一个在左边(消息的接收者),一个在右边。 Ruby (?:
) 中只有一个三元运算符,但是 a) 右边没有两个操作数,它的三个操作数与运算符交错(像这样 a ? b : c
) 和 b) 它不能超载。
请注意,这与名称%
无关,它与运算符语法有关:
puts Test2::ConstString.% "test", "test2"
# this is a string with test and test2
#=> nil
目前正在研究一些元编程的想法,先介绍一下:
我可以将 class
或 module
中的字符串 'template' 定义为 Constant
并在以后像这样使用它:
class Test1
ConstString = %(the string in here is %{instring})
end
puts Test1::ConstString % { instring: "test" }
#=> the string in here is test
问题是
一个。基于基准测试,仅仅定义一个函数可以做同样的事情快 3 倍(基准是 1000000.times):
user system total real
Constant: 1.080000 0.000000 1.080000 ( 1.087187)
Function: 0.350000 0.000000 0.350000 ( 0.346578)
b。我想将它们与常规函数分开,因为我想如何使用它们。
所以我决定创建一个新的 class 来继承 Proc...
并包含一个 module
以投入 Percent/Modulo 语法。
module ProcPercentSyntax
def %(*args)
self.call(*args)
end
end
class TestFromProc < Proc
include ProcPercentSyntax
end
class Test2
ConstString = TestFromProc.new { |x, y| %(this is a string with #{x} and #{y}) }
end
这样我就可以这么叫了!
puts Test2::ConstString % "test", "test2"
但是...
#=> this is a string with test and
令人不安的是没有抛出任何错误。
为了确保这不是另一个问题,我继续这样做了:
module ProcNotPercentSyntax
def make(*args)
self.call(*args)
end
end
class TestFromProc < Proc
include ProcNotPercentSyntax
end
puts Test2::ConstString.make "test", "test2"
还有...
#=> this is a string with test and test2
请原谅这个问题的零星性质,我将这样总结我的意图:
Why does the method seem to miss out on the second given parameter when using
%
as a method name?
puts Test2::ConstString % "test", "test2"
But...
#=> this is a string with test and
不是,那是不是的结果。结果是:
# this is a string with test and
# test2
#=> nil
Disconcertingly without any error thrown.
为什么会出现错误?用两个参数调用 puts
是完全合法的,这就是你在这里所做的。你会期待什么
puts 1+1, 3
打印?完全一样!
Why does the method seem to miss out on the second given parameter when using
%
as a method name?
%
是一个 二元 运算符,类似于 <<
或 |
。它只需要两个个操作数,一个在左边(消息的接收者),一个在右边。 Ruby (?:
) 中只有一个三元运算符,但是 a) 右边没有两个操作数,它的三个操作数与运算符交错(像这样 a ? b : c
) 和 b) 它不能超载。
请注意,这与名称%
无关,它与运算符语法有关:
puts Test2::ConstString.% "test", "test2"
# this is a string with test and test2
#=> nil