2009-11-25 75 views
8

我正在學習Ruby。我的背景是C++/Java/C#。總的來說,我喜歡這種語言,但是我爲什麼有很多不同的方式來完成同一個事情,每個都有自己稍微不同的語義,有點困惑。例如,爲什麼Ruby中有這麼多不同的方法來做同樣的事情?

以字符串創建爲例。我可以使用'','「,q%,Q%或%來創建字符串。有些形式支持插值。其他形式允許我指定字符串分隔符。

爲什麼有五種方法來創建字符串文字?爲什麼我會使用非插值字符串? %語法對引用文字有什麼優勢?

我知道Ruby中的redundency必須有價值,但我未經訓練的眼睛並沒有清楚地看到它。請賜教。

回答

15

爲什麼我會使用非插值字符串?

當然你不想插值。例如,也許您輸出一些文件有關的字符串插值:

'Use #{x} to interpolate the value of x.' 
=> "Use #{x} to interpolate the value of x." 

請問%語法有什麼優勢引述文字?

它可以讓你寫串更自然,不帶引號,或當你不想逃避很多東西,類似於C#的字符串文字前綴@

%{The % syntax make strings look more "natural".} 
=> "The % syntax makes strings look more \"natural\"." 

%{<basket size="50">} 
=> "<basket size=\"50\">" 

還有許多其他%-notations:

%w{apple banana #{1}cucumber} # [w]hitespace-separated array, no interpolation 
=> ["apple", "banana", "\#{1}cucumber"] 

%W{apple banana #{1}cucumber} # [W]hitespace-separated array with interpolation 
=> ["apple", "banana", "1cucumber"] 

# [r]egular expression (finds all unary primes) 
%r{^1?$|^(11+?)\1+$} 
=> /^1?$|^(11+?)\1+$/ 

(1..30).to_a.select{ |i| ("1" * i) !~ %r{^1?$|^(11+?)\1+$} } 
=> [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] 

%x{ruby --version} # [s]hell command 
=> "ruby 1.9.1p129 (2009-05-12 revision 23412) [x86_64-linux]\n" 

還有%s(用於符號)和其他一些人。

爲什麼有五種方法來創建字符串文字?

這不是非常不尋常的。例如,考慮C#,它有幾種不同的方式來生成字符串:new String(); ""; @""; StringBuilder.ToString()等等。

+1

「自然」是非常主觀的。 「非常不尋常」不是創建語言功能的動機。 – skrat 2012-02-07 16:46:10

+1

「自然」具有很高的主觀性,但「更少且更容易輸入字符來表示完全相同的東西」不是,而且是創建語言功能的一個很好的動機。 – 2012-02-07 18:34:19

1

很多ruby的語法都是從perl派生的,就像使用q來將幾個單詞引入一個字符串中一樣。這可能是造成這麼大變化的主要原因。

3

我不是Ruby專家,但你有沒有聽說過「syntactic sugar」這個詞?基本上一些編程語言提供不同的語法來完成相同的任務。由於他以前的編程/語法經驗,有些人可以找到比其他人更容易的方法。

+0

確實。顯然,Ruby在更多場合使用別名/同義詞。例如,數組中元素的數量可以用'count','length'或'size'來檢索。用於數組的相同屬性的不同單詞,但是通過它,您可以爲您的代碼選擇最合適的單詞:是否需要您正在收集的_number_項,數組的_length_或當前的_size_結構。從本質上講,它們都是一樣的,但選擇正確的單詞可能會使代碼更易於閱讀,這是該語言的一個很好的屬性。 – 2016-10-10 18:59:10

2

在大多數情況下,您最終會使用普通的字符串分隔符。單引號和雙引號的主要區別是雙引號允許插入變量。當你因爲他們是內部字符串的一部分不能使用引號

puts 'this is a string' 
# => this is a string 
puts "this is a string" 
# => this is a string 
v = "string" 
puts 'this is a #{v}' 
# => this is a #{v} 
puts "this is a #{v}" 
# => this is a string 

%q%Q是有用的。 例如,你可能最終寫

html = %Q{this is a <img src="#{img_path}" class="style" /> image tag} 

在這種情況下,除非你想逃避內部屬性分隔符,你不能使用雙引號作爲分隔符。另外,您不能使用單引號,因爲img_path變量不會被插值。

0

如果您的字符串包含大量特殊字符(如反斜槓,#{}等),並且您不希望全部轉義,則可以使用非插值字符串。

如果您的字符串包含大量需要轉義的引號,那麼您將使用不同的分隔符。

如果你的字符串有很多行會使正常的字符串語法看起來不靈活,那麼你會使用heredocs。

0

Ruby借鑑了很多語言的構造和思想。兩個最明顯的影響是Smalltalk和Perl。

根據您對Smalltalk或Perl的安慰,您可以選擇不同的構造來做同樣的事情。

1

另一個原因是對非插值字符串性能略有提升。使用''vs'「意味着Ruby不必考慮字符串內部的內容。所以你會看到人們使用單引號作爲數組鍵或符號,因爲它們更快。對於什麼是值得的,我將包括一個小基準。

require 'benchmark' 

Benchmark.bmbm(10) do |x| 
    x.report("single-quote") do 
    for z in 0..1000000 
     zf = 'hello' 
    end 
    end 

    x.report("double-quote") do 
    for z in 0..1000000 
     zf = "hello" 
    end 
    end 

    x.report("symbol") do 
    for z in 0..1000000 
     zf = :hello 
    end 
    end 
end 

產量:

Rehearsal ------------------------------------------------ 
single-quote 0.610000 0.000000 0.610000 ( 0.620387) 
double-quote 0.630000 0.000000 0.630000 ( 0.627018) 
symbol   0.270000 0.000000 0.270000 ( 0.309873) 
--------------------------------------- total: 1.580000sec 
0

除了約翰的回答線: 快速黑客,我最後往往是從我的Ruby腳本中運行的Perl或者sed的一個班輪使用grep語法。能夠使用%[ ]類型語法意味着我可以簡單地從終端複製粘貼我的正則表達式

0

最初的問題是爲什麼Ruby中有很多稍微不同的方法來做事。

有時候,不同的東西是明智的:引用是一種很好的情況,其中不同的行爲需要不同的語法 - 非/插值,交替引用字符等 - 和歷史因素導致像%x()vs``這樣的同義詞,在Perl中。

同義詞問題 - [] .size [] .length [] .count - 感覺像是在語言對於IDE來說過於隨機的世界中有幫助的嘗試:猴子修補和奇怪的嚴格但動態的打字組合使運行時錯誤成爲編碼中不可避免和令人沮喪的部分,所以人們試圖通過提供同義詞來減少問題。不幸的是,他們最終弄亂了習慣於不同方法的程序員做不同的事情。

的「如此相似但不完全」的問題,例如...

$ ruby -le 'e=[]; e << (*[:A, :B])' 
-e:1: syntax error, unexpected ')', expecting :: or '[' or '.' 
$ ruby -le 'e=[]; e << *[:A, :B]' 
-e:1: syntax error, unexpected * 
$ ruby -le 'e=[]; e.push(*[:A, :B])' 
$ 

...真的只能被看作是一個缺陷。每種語言都有它們,但它們通常比這更神祕。

然後在Rubocop編碼標準中存在一個普通的任意'使用失敗而不是加註,除非你只是重新拋出一個異常'廢話。

Ruby中有一些不錯的東西,但真的 - 我寧願編寫一些更好的東西。

相關問題