最近我爲 prettier 寫了一個 Ruby 版本的插件 plugin for prettier,在過程當中我發現 Ruby 語言中不少奇怪的地方(經過須要考慮 AST 的每一個節點類型以及結構的每一個變體),我發現一些有趣的事情,並在這裏與你分享。git
Ruby 中的 case 表達式與其餘語言的 Switch 語句很是類似,它們提供基於一個值來處理不一樣邏輯分支的方法。但你也可使用沒有謂詞的 case 表達式,github
case when foo == 1 ... when bar == 2 ... end
這在功能上等同與檢查 if foo == 1
和 elsif bar == 2
。正則表達式
Flip-flops(名稱來自電路設計)是最難懂的操做符之一。這篇文章有一個很好的解釋。shell
lines.each do |line| next unless (line =~ start_pattern)..(line =~ end_pattern) puts line end
基本上,這將遍歷一些列表 lines
,打印知足開始和結束時間條件的每個行。數組
你知道 Ruby 還有 for
循環嗎?他們看起來像這樣:ruby
for num in [1, 2, 3] do puts num end
這也意味着 in
是一個保留字,因此你也不能將其用做標識符。less
Ruby 有兩個特殊的 Block 塊,它們內置在語言中讓你能夠 hook 腳本的開始和退出。我認爲它們對於腳本編寫特別有用,而對於應用程序級邏輯則不那麼有用。他們看着像是:插件
BEGIN { puts 'script has started' } END { puts 'script has ended' }
有趣的是這些 Block 不支持 do...end
寫法,我不知道爲何。設計
在 Ruby 中二進制,八進制和十六進制數字有一種特殊的語法表示,如下全部語句的值都爲 true:code
0b10 == 2 # 二進制 0o10 == 8 # 八進制 0x10 == 16 # 十六進制
最重要的是,您甚至能夠刪除八進制數重點額 o
而使用前綴 0
,010 == 8
即爲 true,若是不當心這個可能很容易出現意想不到的問題!
Procs 和 lambdas 都有一個使用方括號調用的特殊語法,好比:
add = ->(left, right) { left + right } add[3, 4] # => 7
傳遞給方括號的參數數量與傳遞給 proc 的數量一致。所以,對於沒有元素的 proc 或 lambdas,您能夠徹底去掉參數,如:
greet = -> { puts 'Hello, world!' } greet[]
字符串有各類有趣的屬性!下面是一些讓我感到驚訝的事情。
%x
字面量您可能知道反引號表達式(即 ls
),它將生成一個進程在 shell 中執行,而後將 stdio 輸出返回給調用者。(要當心請不要本身 RCE)
你可能不知道 %x
字面量,它們其實是同一個東西(即 %x[ls]
)。不要與其餘 %-字面量 混淆,像 %w
和 %i
建立數組!
%q
字面量你可使用 %q
和 %Q
來建立一個字符串字面量(好比 %q[abc]
)。這實際上和使用單引號和雙引號是同樣的,區別是後者不須要對雙引號進行轉移,很是方便。
Ruby 中正常的字符串插值看起來像這樣 "a #{b} c"
,其中 b
是會響應 to_s
的變量( 即除 BasicObject
以外的任何東西 )。可是你知道若是像插入一個實例(instance)、類或全局變量能夠不用大括號,也就是下面的代碼徹底有效:
@instance = 'instance' @@class = 'class' $global = 'global' "#@instance #@@class #$global" == 'instance class global' # => true
它甚至能夠在正則表達式中使用!若是用上面的表達式中的 /
替換雙引號,你將得到帶有插值變量的正則表達式。
?
字面量我之因此把最好的留到最後,由於這真的是挺奇怪,如下兩個語句在 Ruby 中都有效:
?a == 'a' ?\M-\C-a == "\x81"
事實證實 ?
容許您建立長度爲 1 的字符串,並引入一些特殊的附加功能。有關進一步說明,請直接從 Ruby 文檔中獲取:
\cx or \C-x 控制字符,其中 x 是一個可打印的 ASCII 字符 \M-x 元字符,其中 x 是一個可打印的 ASCII 字符 \M-\C-x 元控制字符,其中 x 是一個可打印的 ASCII 字符 \M-\cx 如上 \c\M-x 如上 \c? or \C-? 刪除,ASCII 7Fh (DEL)
在Ruby中,您可使用 ()
來表示 nil
,由於它被視爲沒有語句的空表達式。這致使可以作各類奇怪的事情,好比 !()
,其值爲 true
。
Ruby很是具備表現力,它爲您提供了許多方法。這與許多語言造成了鮮明的對比(例如,在 Python 之蟬 (The Zen of Python) 中,它指出 「應該有一種 - 最好只有一種 - 顯而易見的方式」)。
固然這種方法有權衡。雖然它能夠爲您提供快速生產代碼的能力,但若是有無數類似的處理方法,它也會下降閱讀效率。這是 prettier 和其 Ruby 插件的明確目標之一 - 咱們正在嘗試標準化,以便您能夠回到編寫應用程序代碼之中。