2016-03-30 21 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方法。

每当有疑问时,您总是可以检查文档以检查方法的作用,以及它的返回值和类型。

相关问题