在如 rails 這樣的開源庫中,我們常常見到這樣的一類寫法:
class_eval <<-RUBY, __FILE__, __LINE__ + 1
def xxx
# do something here
end
RUBY
令人困惑不已,
不過這里的知識點非常簡單,只要掌握了 heredoc 與 eval 的用法,就很好理解這里的代碼了,
heredoc
heredoc 是一種定義多行字串的方法,同時保持原始縮進和格式,相當于 JavaScript 中的 ``,
heredoc 以 <<- 開頭,跟上一個隨意的單詞,最后再以這個字串結束:
multi_str = <<-FOO
1
2
3
FOO
puts multi_str
多行字串會保留所有的縮進,并且在尾部會帶上 \n 換行符,
對于換行符,可以使用 chomp 來去除:<<-FOO.chomp,
如果你在縮進的情況下宣告 heredoc,可能會變成這樣,十分丑陋:
multi_str = <<-FOO
1
2
3
FOO
如果保持縮進:
multi_str = <<-FOO
1
2
3
FOO
最后的輸出結果也會帶上 1 所有縮進,這里可以使用 ~ 代替 -,或是使用 strip,
multi_str = <<~FOO
1
2
3
FOO
multi_str = <<-FOO.strip
1
2
3
FOO
這兩種方式都會以第一行為標準,在所有行的開頭,洗掉空格,
eval
eval 在很多腳本語言中都存在,它可以讓我們將字串作為代碼執行,
ruby 中存在多個 eval 方法,比如 eval class_eval module_eval instance_eval 等,
他們分別可以實作不同的 eval 功能,
以 class_eval 為例:
class Foo
STR = <<-RUBY
def say
p 'I am Foo'
end
RUBY
Module.class_eval STR
end
Foo.say
我們可以輕松將字串變成方法,
代碼分析
現在我們終于可以看懂這段代碼了,它其實就是使用了 heredoc 多行字串,將字串里變成了一個真正的 ruby 方法,
class_eval <<-RUBY, __FILE__, __LINE__ + 1
def xxx
# do something here
end
RUBY
那么后面的 __FILE__, __LINE__ + 1 有什么用呢?
其實我們完全可以不傳這兩個引數,
但是加入我們字串生成的方法報了錯該怎么辦呢?一般我們的方法報錯都會有檔案名、行號,
eval 使用字串生成方法,自然沒有這些東西,所以我們傳入當前檔案的檔案名,和當前行的行號+1,來幫助 Ruby 生成更好的報錯資訊,
(完)
作者:幾乎一米八的徐某某 出處:Aero Blog (https://www.cnblogs.com/xhyccc/) 本文著作權歸作者和博客園共有,歡迎轉載,但未經作者同意必須在文章頁面給出原文連接,否則保留追究法律責任的權利,轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/544585.html
標籤:其他
下一篇:RabbitMQ中間件
