2016-03-30 9 views
1

Codecademy lehrt, dass man Kette mehrere Methoden zusammen als solche:Ist es wichtig, wie eine String-Methode verwendet wird?

user_input.method1.method2.method3 

sie jedoch in einer späteren Lektion wie dies einige Methoden an:

user_input = gets.chomp 
user_input.downcase! 

ich sie kombiniert:

user_input = gets.chomp.downcase! 

Wenn ich es so benutze:

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

Ich erhalte einen Fehler "undefined method `include?'". Wenn ich es in den folgenden ändern, funktioniert es gut:

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

Ich bin ratlos. Ich mache mir Sorgen, ob das eine Eigenart mit ihrer Konsole ist oder ob es genau so ist, wie ich es in Ruby machen sollte. Wenn mir jemand sagen könnte, welcher Weg richtig ist, würde ich es begrüßen. Wenn beide richtig sind, ist das auch in Ordnung.

+0

Verwenden Sie 'downcase' anstelle von' downcase! '? – YOU

Antwort

0

Das Problem, auf das Sie stoßen, ist mit der Bang-Methode downcase!.

Dies ist im Grunde sagen "muate die ursprüngliche Zeichenfolge, so dass es downcase" ist. Der wichtige Teil ist, dass dies nil zurückgibt. Als solche rufen Sie tatsächlich include? auf nil.

Wenn Sie stattdessen die Non-Bang-Methode downcase verwenden, heißt es: "Verkleinern Sie die zuvor angekettete Sache, aber mutieren Sie nicht das Original". Der Hauptunterschied besteht darin, dass das Ergebnis anstelle von nil zurückgegeben wird. Hier

ein Beispiel:

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

Willkommen bei Rubin! Während Ihre Ausbildung bei Codeacademy begrenzt sein könnte, werden Sie während Ihrer gesamten Karriere weiterhin auf die API-Dokumentation verweisen. Die API-Dokumentation beschreibt, was die Sprache (oder eine Bibliothek) für Sie tut. In diesem Fall verwenden Sie downcase!, was, wie ein Kommentator hervorhebt, nicht immer einen String zurückgibt. Wenn es keine Aktion ausführt, gibt es null zurück. Nil ist ein Objekt in Ruby (wie alles andere), aber das 'include?' Methode ist nicht für Null definiert, was Ihren Fehler erklärt. (Es ist einer der häufigsten Fehler in Ruby, lernen Sie seine Bedeutung.)

Also, in der Tat, was hier bricht ist nicht Ihre Methode Kette. Es ist so, dass eine der intermediären Methoden keinen Wert des erwarteten Typs zurückgibt (null statt irgendeiner Art von String).

0

Chaining nicht zerstörende Verfahren wie:

string.chomp.downcase... 

hat den Vorteil, dass der Code präzise ist, aber es ist nicht effizient, wenn Sie nicht daran interessiert, in den ursprünglichen Zustand des Objekts sind, und wollen nur das Endergebnis, weil Es erstellt während der Kette Zwischenobjekte.

Auf der anderen Seite, destruktive Methoden der Reihe nach auf das gleiche Objekt anwenden:

string.chomp! 
string.downcase! 
... 

ist effizienter, wenn Sie nicht den ursprünglichen Zustand des Objekts halten müssen, aber ist nicht präzise.

Kombinieren von Methoden, die ein Objekt von einer anderen Klasse zurückkehren können (insbesondere nil) als:

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

falsch ist, weil das Ergebnis nil an irgendeinem Punkt in der Kette werden kann.

eine potenziell nil -returning Methode nur auf die letzte Position anwenden, wie Sie tut:

wenn Sie string zu immer ein String ist, und können leicht zu einem Fehler führen, wie Sie noch nicht nützlich
string = gets.chomp.downcase! 

ist erwarten hat getan.

Wenn Sie diese Methoden in Ihnen Beispiel Kette wollen, vielleicht können Sie dies tun:

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

Erstens Sie bei noch nicht vollständig verstehen, Zuweisung von Werten an Variablen werden durch = getan, und dass Sie überprüfen können, welcher Variablentyp es ist, indem Sie .class an etwas anfügen.

Beachten Sie Folgendes:

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

Nun zweitens sei darauf hingewiesen, dass die Rückgabewerte aller Methoden sind alle unterschiedlich. Aber sie alle können in zwei Typen unterschieden werden:

Methods, dass:

  1. Rückkehr Selbst
  2. Rückkehr alles andere als selbst

Beispiel für 1.

- Methoden, die self zurückgeben, die man Methoden nennen könnte, die den gleichen Objekttyp zurückgeben, der in unserem speziellen Fall eineist

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 

Beachten Sie, dass deleted_downcased_name und deleted_downcased_name2 gleich sind, weil Sie die verkettete Methoden behandeln könnte, als ob Sie die Rückgabewerte sind Chaining, die ‚John‘ ist -> ‚john‘ -> ‚jon‘.

Beispiel für 2

- Methoden, die alles andere als selbst zurückkehren, die Sie Methoden sagen könnte, die einen anderen Typ zurückgeben.

In unserem speziellen Fall downcase! kehrt String entweder eine String oder NilClass(reference here)

  • Rückkehr String wenn die Zeichenfolge ändert oder
  • nil Rückkehr, wenn der String bereits mit (keine Veränderung) beginnen downcased wird.

oder eine andere Methode String: (reference here)

  • true oder false Rückkehr

Dies ist, wo der Methoden Chaining wird nicht funktionieren (löst einen Fehler), wenn Sie versuchen, eine zu verwenden, String-Methode als Kette zu Nullwert.

Betrachten Sie die folgende

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 

Der Fehler, der oben ist, weil downcased_name eine Art von NilClass ist, wo Sie erwarten, es ist eine Art von String zu sein. Daher können Sie keine String-Methode mehr verketten. Sie können String Methoden nur auf einen String Werttyp verketten. Ebenso können Sie Number Methoden nur auf einen Number Werttyp verketten.

Im Zweifelsfall können Sie in der Dokumentation immer nachsehen, was eine Methode macht und was der Rückgabewert und Typ ist.

Verwandte Themen