2016-03-30 15 views
1

Codeacademy教導我們,你可以將多個方法一起這樣的:使用字符串方法的方式是否重要?

user_input.method1.method2.method3 

然而,在後面的課程,他們展示了一些方法是這樣的:

user_input = gets.chomp 
user_input.downcase! 

我將它們結合在一起:

user_input = gets.chomp.downcase! 

當我這樣使用它:

user_input = gets.chomp.downcase! 
if user_input.include? "s" 
... 

我收到一個錯誤"undefined method `include?'"。如果我將其更改爲以下版本,則工作正常:

user_input = gets.chomp 
user_input.downcase! 
if user_input.include? "s" 
... 

我不知所措。我擔心這是否是他們控制檯的怪癖,或者這是我應該如何在Ruby中做的。如果有人能告訴我哪種方式是正確的,我會很感激。如果兩者都是對的,那也沒關係。

+0

只是使用'downcase'而不是'downcase!'? – YOU

回答

0

您遇到的問題是與爆炸方法downcase!

這基本上是說「改變原始字符串,使它是無用的」。 重要的是這返回nil。因此,您實際上在nil上調用include?

如果您使用非爆炸方法downcase來代替它,它會說「壓倒之前鏈接的東西,但不要改變原件」。關鍵區別在於它返回結果而不是nil

下面是一個例子:

str = "ABCD" 
str.downcase! 
=> nil 

str 
=> "abcd" 

str = "ABCD" 
str.downcase 
=> "abcd" 

str 
=> "ABCD" # Note str is still unchanged unless you set str = str.downcase 
0

歡迎紅寶石!雖然您在Codeacademy的學徒生可能有限,但您在整個職業生涯中仍將繼續參考語言API文檔。 API文檔是對語言(或庫)爲您做什麼的描述。在這種情況下,您使用downcase!,正如一位評論者指出的,它並不總是返回一個字符串。當它不採取任何行動時,它返回零。無(Nil)是Ruby中的一個對象(就像其他的一樣),但是'include?'方法沒有被定義爲nil,這就解釋了你的錯誤。 (這是Ruby中最常見的錯誤之一,請了解其含義。)

所以,實際上,這裏突破的不是你的方法鏈。這是一種中間方法沒有返回你期望的類型的值(無,而是某種類型的字符串)。

0

鏈非破壞性的方法,如:

string.chomp.downcase... 

的優點是代碼簡潔,但效率不高,如果你不感興趣的對象的原始狀態,只是想最後的結果,因爲它在鏈中創建中間對象。

在另一方面,運用破壞性的方法順序相同的對象:

string.chomp! 
string.downcase! 
... 

更有效的,如果您不需要保留對象的原始狀態,但不簡潔。

可能返回不同的類(特別是nil)作爲的一個目的結合的方法:

string = gets.chomp!.downcase!... 

是錯誤的,因爲其結果可以在鏈的某一點變得nil

只在最後一個位置上應用的潛在nil -returning方法爲你做:

string = gets.chomp.downcase! 

仍然是沒有用的,如果你希望string永遠是一個字符串,很容易導致一個錯誤,你沒有。

如果你想鏈在您例如這些方法,也許你可以這樣做:

user_input = gets.tap(&:chomp!).tap(&:downcase!) 
if user_input.include?("s") 
... 
1

首先,如果你還沒有完全理解,給變量的賦值是通過=完成,你可以通過在任何東西上附加.class來檢查它是什麼類型的變量。

考慮以下幾點:

name = 'John' 
puts name 
# => John 
puts name.class 
# => String 

如今,其次,應該指出的是,所有方法的返回值都是不同的。但是,所有的人都可以被識別爲兩種類型:

中的方法:

  1. 迴歸自我
  2. 不是自我其他
  3. 任何回報

示例1

- 返回self的方法,您可以說返回相同類型的對象的方法,在我們的具體情況下,這是String

name = 'John' 
puts name 
# => 'John' 
puts name.class 
# => String 

downcased_name = name.downcase 
puts downcased_name 
# => john 
puts downcased_name.class 
# => String 

deleted_downcased_name = downcased_name.delete('h') 
puts deleted_downcased_name 
# => jon 
puts deleted_downcased_name.class 
# => String 

# All of the above can be just simplified into: 

deleted_downcased_name2 = 'John'.downcase.delete('h') 
puts deleted_downcased_name2 
# => jon 
puts deleted_downcased_name2.class 
# => String 

注意deleted_downcased_namedeleted_downcased_name2都是一樣的,因爲你可以,如果你要串聯的返回值是「約翰」治療方法鏈接 - >「約翰」 - >「喬恩」。

例2種

- 方法,返回什麼,但自我,你可以說,返回不同類型的方法。

在我們的具體情況下,字符串的downcase!情況傳回StringNilClass(reference here)

  • 返回String如果字符串的變化,或
  • 返回nil如果字符串已downcased與(沒有變化)開始。

或其他字符串的方法: (reference here)

  • 返回truefalse

這方法行不通,其中鏈(引發錯誤),當您嘗試使用字符串方法作爲一個鏈向零值。

考慮以下

name = 'mary' 
puts name 
# => 'mary' 
puts name.class 
# => String 

downcased_name = name.downcase! 
puts downcased_name 
# => nil 
puts downcased_name.class 
# => NilClass 

downcased_name.delete('h') 
# => This will raise the following error 
# NoMethodError: undefined method `delete' for nil:NilClass 

上述錯誤是因爲downcased_name是你期待它是一個類型的String類型的NilClass。因此你不能鏈接任何字符串方法了。您只能在String類型的值上鍊接String方法。同樣,您只能在Number類型的值上鍊接Number方法。

每當有疑問時,您總是可以檢查文檔以檢查方法的作用,以及它的返回值和類型。

相關問題