目前我正在玩一些元编程思想,让我先介绍一下:
我可以定义一个字符串'模板'在import UIKit
class ViewController: UIViewController {
@IBOutlet weak var funFactLabel: UILabel!
@IBOutlet weak var showButton: UIButton!
var factProvider = FactProvider()
override func viewDidLoad() {
super.viewDidLoad()
funFactLabel.text = factProvider.randomFact()
}
@IBAction func showFact() {
funFactLabel.text = factProvider.randomFact()
let newColor = BackgroundColorProvider.randomColor()
view.backgroundColor = newColor
showButton.tintColor = newColor
}
}
或class
作为module
并稍后使用它:
Constant
问题是
一个。基于一个基准,只需定义一个函数可以做同样的事情3倍(Benchmark是1000000.times):
class Test1
ConstString = %(the string in here is %{instring})
end
puts Test1::ConstString % { instring: "test" }
#=> the string in here is test
湾我希望将这些与常规函数分开,因为我想要使用它们。
所以我决定创建一个继承Proc的新类...
并包含 user system total real
Constant: 1.080000 0.000000 1.080000 ( 1.087187)
Function: 0.350000 0.000000 0.350000 ( 0.346578)
以输入Percent / Modulo语法。
module
那样,我可以这样称呼它!
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
作为方法名称时,为什么该方法似乎错过了第二个给定参数?
答案 0 :(得分:4)
puts Test2::ConstString % "test", "test2"
但是...
#=> this is a string with test and
不,那是不的结果。结果是:
# this is a string with test and
# test2
#=> nil
令人不安地没有任何错误抛出。
为什么会出错?用两个参数调用puts
是完全合法的,这就是你在这里所做的。你会期待什么
puts 1+1, 3
打印?它完全一样!
当使用
%
作为方法名称时,为什么该方法似乎错过了第二个给定参数?
%
是二进制运算符,如<<
或|
。它只需要两个操作数,一个在左边(消息的接收者),一个在右边。 Ruby中只有一个三元运算符(?:
),但a)在右边没有两个操作数,它的三个操作数与运算符交错(如a ? b : c
)和b)它不能超载。
请注意,这与名称%
无关,它与运算符语法有关:
puts Test2::ConstString.% "test", "test2"
# this is a string with test and test2
#=> nil