利用 Ruby 在其基本特性中提供的自由,我發現為語言中使用的大多數運算子設定別名相當容易,但Regexp#~ 一元前綴運算子更棘手。
第一個天真的方法是在 Regexp 類本身中給它取別名
class Regexp
alias hit ~@ # remember that @ stands for "prefix version"
# Note that a simple `alias_method :hit, :~@` will give the same result
end
正如在下面的一些答案中指出的那樣,這種方法在某種程度上具有點符號呼叫形式的功能,例如/needle/.hit. 但是,嘗試執行hit /needle/會提高undefined method main:Object (NoMethodError)` 的命中率
所以另一種簡單的方法是在 中定義這個方法Object,比如
class Object
def ~@(pattern)
pattern =~ $_
end
end
但是,這行不通,因為$_全域變數實際上是本地系結的,并且不會保留它在呼叫背景關系中的值,即$_始終nil在前一個片段中。
所以問題是,是否有可能使運算式hit /needle/恢復與~ /needle/?相同的結果?
uj5u.com熱心網友回復:
對我來說很好用:
class Regexp
alias_method :hit, :~ # both of them work
# alias hit ~ # both of them work
end
$_ = "input data"
/at/.hit #=> 7
~/at/ #=> 7
/at/.hit #=> 7
~/at/ #=> 7
uj5u.com熱心網友回復:
因此,由于完成的問題現在抑制了它,主要障礙是 的范圍狹窄$_。那是trace_var可以拯救的地方:
trace_var :$_, proc { |nub|
$last_explicitly_read_line = nub
#puts "$_ is now '#{nub}'"
}
def reach(pattern)
$last_explicitly_read_line =~ pattern
end
def first
$_ = "It’s needless to despair."
end
def second
first
p reach /needle/
$_ = 'What a needlework!'
p reach /needle/
end
p reach /needle/
second
p reach /needle/
$_ = nil
p reach /needle/
因此,基本思想是將$_每次更改的值存盤在另一個變數中,該變數可在其他后續呼叫背景關系中訪問。這里它是用另一個全域變數實作的(不是本地系結的,$_當然不像),但是用其他實作可以獲得相同的結果,比如在 上定義類變數Object。
也可以嘗試使用諸如binding_of_caller或binding_ninja 之類的東西,但我自己的方法失敗了,當然它還帶有其他依賴項,這些依賴項有其自身的限制。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/370153.html
上一篇:Ruby陣列的餅圖
