2009-07-09 8 views
0

Warum ist das nicht arbeiten:Binär oder "|" in Ruby

>> s = "hi"                
=> "hi"                 
>> s == ("hi"|"ho")              
NoMethodError: undefined method `|' for "hi":String      
from (irb):2               
>> 

Ich verstehe es nicht .. Gibt es eine Lösung für diese Art von Syntax? Da

s == ("hi"|"ho") 
#is shorther than 
s == "hi" || s == "ho" 
+0

Diese Frage überhaupt nicht sinnvoll.Bitweises ODER der Strings "hi" und "ho" ist gleich "ho". Wenn s == "hi", würde Ihr vorgeschlagener Ausdruck * also false * zurückgeben. Wenn Sie verschiedene Zeichenfolgen verwenden, ist das Ergebnis der bitweisen Operation möglicherweise noch unsinniger. – molf

Antwort

9

Ja, der bitweise Operator | ist nicht in der String-Klasse definiert: http://ruby-doc.org/core/classes/String.html

diese Ausdruckskraft für Bedenken Sie:

["hi", "ho"].include? myStr 

irb(main):001:0> s = "hi" 
=> "hi" 
irb(main):002:0> ["hi", "ho"] 
=> ["hi", "ho"] 
irb(main):003:0> ["hi", "ho"].include? s 
=> true 
irb(main):004:0> s = "foo" 
=> "foo" 
irb(main):005:0> ["hi", "ho"].include? s 
=> false 
+0

Ja, wenn Sie eine Liste von Werten haben, die Sie testen möchten, testen Sie einfach, ob die Liste den Wert enthält, anstatt jedes Element einzeln zu durchsuchen, um zu sehen, ob sie übereinstimmen. – Chuck

5

In den meisten Hochsprachen dass Syntax nicht funktionieren, müssen Sie die längere Syntax bleiben:

s == "hallo" || s == "ho"

Beachten Sie, dass | ist ein bitweises oder, während || ist eine regelmäßige oder

1

Sie es so machen könnte funktionieren:

irb> class Pair 
     def initialize(strA,strB) 
     @strA,@strB = strA,strB 
     end 
     def ==(string) 
     string == @strA || string == @strB 
     end 
     def |(other) 
     Pair.new(self,other) 
     end 
    end 
#=> nil 
irb> class String 
     def |(other) 
     Pair.new(self,other) 
     end 
     alias old_equals :== 
     def ==(other) 
     if other.kind_of? Pair 
      other == self 
     else 
      old_equals other 
     end 
     end 
    end 
#=> nil 
irb> ("one"|"two") == "one" 
#=> true 
irb> ("one"|"two") == "two" 
#=> true 
irb> ("one"|"two") == "three" 
#=> false 
irb> "one" == ("one"|"two") 
#=> true 
irb> "three" == ("one"|"two"|"three") 
#=> true 

Aber da dies beinhaltet einige Affen Patchen von einer ziemlich lowlevel Klasse, würde ich nicht raten, sich auf sie. Andere Leute werden es hassen, Ihren Code zu lesen.

+3

Ich bin ... Ich werde dich nicht abmelden, weil das wirklich eine sehr saubere Antwort auf die Frage ist ... aber wenn du jemals in der Nähe einer Codebasis kommst, die ich damit behalte, habe ich einen halben Stein in einem Socke mit deinem Namen liebevoll darin eingraviert. Klingt gut? –

+0

oh einverstanden. Nur weil es getan werden kann, heißt es nicht, dass es sein sollte. – rampion

+0

Ich habe das geändert, weil es schlau ist, aber ich stimme dir zu, dass ich es vermeiden würde, so etwas in Code zu tun, von dem niemand außer dir selbst erwartet. –

1

Ruby unterstützt binäre 'oder' und other binary operations auf Werte vom Typ Fixnum und Bignum, dh jede ganze Zahl. Bitwise-Operationen werden für Strings oder andere Typen nicht unterstützt, soweit ich weiß.

Wie andere Leute erwähnt haben, möchten Sie wahrscheinlich etwas anderes als binäre Operationen insgesamt. Sie können jedoch leicht ganzzahlige Darstellungen von Zeichen zu bekommen, so können Sie die Zeichen vergleichen, wie so:

a = "Cake" 
b = "Pie" 
puts a[0] | b[0] # Prints "83" - C is 67 and P is 80. 

Sie können ein Array der Vergleiche leicht mit einigen Conversions.

a = "Cake" 
b = "Pie " # Strings of uneven length is trivial but more cluttered. 

a_arr = a.split(//) 
b_arr = b.split(//) 
c_arr = [] 

a.each_with_index { |char, i| c.push(a[i].to_i | b[i].to_i) } 
# If you *really* want an ASCII string back... 
c = c_arr.collect(&:chr).join 
3

Sie die include? Methode auf Array verwenden können, wenn Sie mehrere == Tests zu tun habe:

["hi", "ho"].include?(s) 

Nicht kürzer für zwei Kontrollen, aber es wird für drei oder mehr kürzer sein.

1

Diese Syntax existiert in keiner Sprache, soweit ich weiß.

Was Sie

s == ("hi"|"ho") 

Wörtlich sagen übersetzt ‚bitweise OR die Saiten‚hallo‘und‚ho‘zusammen und sie dann mit s vergleichen‘. Wenn Sie nicht sehen können, warum dies nicht das ist, was Sie suchen, versuchen Sie, die ASCII-Codes für "hi" und "ho" aufzuschreiben und sie dann bitweise zu verknüpfen. Du wirst komplett Kauderwelsch bekommen.

0

Sie können einen regulären Ausdruck verwenden:

Wie so:

regex = /hi|ho/ 
s = "hi" 
t = "foo" 

s =~ regex 
#=> 0 

t =~ regex 
#=> nil