初心者に警告すべきRuby Gotchasとは何ですか?[閉まっている]


108

私は最近Rubyプログラミング言語を学びましたが、全体としてそれは良い言語です。でも、思ったほど簡単ではなかったのでびっくりしました。より正確には、「最小サプライズのルール」は私にはあまり尊重されていないように見えました(もちろんこれはかなり主観的です)。例えば:

x = true and false
puts x  # displays true!

そして有名な:

puts "zero is true!" if 0  # zero is true!

Rubyの初心者に警告する他の "Gotchas"は何ですか?


@ phrases.insert(0、p)OK @ phrases.insert(p)NOTHINGが発生します@phrases << p#OK
Anno2001

なぜtrue and falsetrueを返すのですか?
ユルゲンポール

3
「x = true and false」は実際には「(x = true)and false」と解釈されるためです。これは演算子の優先順位の問題です。「and」は「=」よりも優先順位が低くなります。他のほとんどの言語は逆の優先順位を持っています、なぜ彼らがRailsでこの順序を選択したのか分かりません、私はそれを非常に混乱させます。「通常の」動作が必要な場合は、単に「x =(true and false)」と入力すると、xはfalseになります。
ミニクォーク、2013

4
別の解決策は、「&&」と「||」を使用することです 「and」と「or」の代わりに:期待どおりに動作します。たとえば、「x = true && false」の場合、xはfalseになります。
MiniQuark 2013

「最小の驚きの原則とは、私の最小驚きの原則を意味します。」en.wikipedia.org/wiki/Ruby_(programming_language)#PhilosophyからPythonでも同じことが言えます。Pythonの作成者についても同様の引用がありましたが、どこにあったのか忘れてしまいました。
DarekNędza2014年

回答:


59

ウィキペディアRubyの落とし穴

記事から:

  • 大文字で始まる名前は定数として扱われるため、ローカル変数は小文字で始める必要があります。
  • 文字$@は、Perlのように変数のデータ型を示すのではなく、スコープ解決演算子として機能します。
  • 浮動小数点数を表すには、その後にゼロの数字(99.0)または明示的な変換(99.to_f)を続ける必要があります。99.数字はメソッド構文の影響を受けやすいため、ドット()を追加するだけでは不十分です。
  • 非ブールデータのブール評価は厳密です。 0""そして[]すべてに評価されますtrue。Cでは、式は0 ? 1 : 0評価されます0(つまり、false)。ただし、Rubyでは、1すべての数値がに評価されるためtrue、が生成されます。のみnilfalse評価されfalseます。このルールの当然の結果として、Rubyメソッドは規則(たとえば、正規表現検索)で成功すると、数値、文字列、リスト、またはその他の偽でない値を返しますが、nilに失敗した場合(例:不一致)に。この規則はまた、唯一の特別なオブジェクトのSmalltalkで使用されているtrueとは、falseブール式で使用することができます。
  • 1.9より前のバージョンには、文字データ型がありません(文字の型を提供するCと比較してくださいchar)。文字列スライスとき、これは驚きを引き起こす可能性があります。"abc"[0]利回り97(文字列の最初の文字のASCIIコードを表す整数を、); 得た"a"用途"abc"[0,1]又は(長さ1のサブストリングを)"abc"[0].chr
  • 表記はstatement until expression、他の言語と等価文(例とは異なりdo { statement } while (not(expression));式がすでにある場合はC / C ++での/ ...)、実際に文が実行されることはありませんtrue。これは、statement until expression実際には構文糖が

    until expression
      statement
    end

    、C / C ++ での同等のwhile (not(expression)) statement;ものstatement if expressionは、以下と同等です。

    if expression
      statement
    end

    ただし、表記

    begin
      statement
    end until expression

    Rubyでは、式がすでに真であっても、実際にはステートメントを1回実行します。

  • 定数はオブジェクトへの参照であるため、定数の参照先を変更すると警告が生成されますが、オブジェクト自体を変更しても警告は生成されません。たとえばGreeting << " world!" if Greeting == "Hello"、エラーや警告は生成されません。これはfinalJavaの変数に似ていますが、Javaとは異なり、Rubyにはオブジェクトを「フリーズ」する機能もあります。

他の言語と著しく異なるいくつかの機能:

  • 条件式の通常の演算子、andおよびorは、通常の優先順位の規則に従いandません。or。Rubyはまた、式演算子持ち||&&期待通りの仕事を。

  • def 内部 defは、Pythonプログラマが期待することはできません。

    def a_method
        x = 7
        def print_x; puts x end
        print_x
    end

    これにより、エラーが発生します x定義されいない。を使用する必要がありますProc

言語機能

  • メソッドの引数を囲む括弧を省略すると、メソッドが複数のパラメーターを取る場合に予期しない結果が生じる可能性があります。Ruby開発者は、マルチパラメータメソッドでの括弧の省略は、将来のRubyバージョンでは許可されなくなる可能性があると述べています。現在(2007年11月)のRubyインタプリタは、()コードのあいまいな意味を避けるために、作成者がを省略しないように促す警告をスローします。使用しないこと()は今でも一般的な慣行であり、と呼ばれるメソッドとともに、Rubyを人間が読み取り可能なドメイン固有のプログラミング言語自体として使用すると特に便利ですmethod_missing()

1
Ruby 1.9にも文字データ型がありません。1.8では、インデックス演算子がFixnumを返しました。1.9では、1文字の文字列をスライスするのと同じです。
ホワイトクォーク、2011

38

初心者は平等法で問題を抱えるでしょう:

  • a == b:aとbが等しいかどうかをチェックします。これは最も便利です。
  • a.eql?b :aとbが等しいかどうかもチェックしますが、より厳密な場合もあります(たとえば、aとbが同じ型であることをチェックする場合があります)。主にハッシュで使用されます。
  • a.equal?b:aとbが同じオブジェクトかどうかをチェックします(同一性チェック)。
  • a === b:caseステートメントで使用されます(「aはbと一致する」と読みます)。

これらの例では、最初の3つの方法を明確にする必要があります。

a = b = "joe"

a==b       # true
a.eql? b   # true
a.equal? b # true (a.object_id == b.object_id)

a = "joe"
b = "joe"

a==b       # true
a.eql? b   # true
a.equal? b # false (a.object_id != b.object_id)

a = 1
b = 1.0

a==b       # true
a.eql? b   # false (a.class != b.class)
a.equal? b # false

なお、==EQL?そして等しい?常に対称である必要があります。a== bの場合、b == aです。

==およびeqlにも注意してください両方とも、等しいエイリアスとしてObjectクラスに実装されていますか?、それであなたが新しいクラスを作成し、==eqlが欲しいなら単純なアイデンティティ以外のものを意味するには、両方をオーバーライドする必要があります。例えば:

class Person
    attr_reader name
    def == (rhs)
      rhs.name == self.name  # compare person by their name
    end
    def eql? (rhs)
      self == rhs
    end
    # never override the equal? method!
end

===方法は異なる動作をします。まず第一にそれは対称的ではありません(a === bはb === aを意味しませ)。すでに述べたように、a === bは「aはbに一致する」と読むことができます。以下にいくつかの例を示します。

# === is usually simply an alias for ==
"joe" === "joe"  # true
"joe" === "bob"  # false

# but ranges match any value they include
(1..10) === 5        # true
(1..10) === 19       # false
(1..10) === (1..10)  # false (the range does not include itself)

# arrays just match equal arrays, but they do not match included values!
[1,2,3] === [1,2,3] # true
[1,2,3] === 2       # false

# classes match their instances and instances of derived classes
String === "joe"   # true
String === 1.5     # false (1.5 is not a String)
String === String  # false (the String class is not itself a String)

ケースの文が基づいている===方法:

case a
  when "joe": puts "1"
  when 1.0  : puts "2"
  when (1..10), (15..20): puts "3"
  else puts "4"
end

これと同等です:

if "joe" === a
  puts "1"
elsif 1.0 === a
  puts "2"
elsif (1..10) === a || (15..20) === a
  puts "3"
else
  puts "4"
end

インスタンスが何らかのコンテナまたは範囲を表す新しいクラスを定義する場合(include?またはmatch?メソッドのようなものがある場合)、次のように===メソッドをオーバーライドすると便利な場合があります。

class Subnet
  [...]
  def include? (ip_address_or_subnet)
    [...]
  end
  def === (rhs)
    self.include? rhs
  end
end

case destination_ip
  when white_listed_subnet: puts "the ip belongs to the white-listed subnet"
  when black_listed_subnet: puts "the ip belongs to the black-listed subnet"
  [...]
end

1
また、a = 'строка'; b = 'строка'; pa == b; a = a.force_encoding 'ASCII-8BIT'; b = b.force_encoding 'UTF-8'; pa == b; pa === b; p a.eql?b; p a.equal?b
ナキロン2010

20
  • サルのパッチ。Rubyにはオープンクラスがあるため、実行時に動的に動作を変更できます...

  • オブジェクトは、またはオーバーライドされた場合、未定義のメソッドに応答する可能性があります。これは、Rubyのメッセージベースのメソッド呼び出しを利用します。RailsActiveRecord システムはこれを使用して大きな効果をもたらします。method_missingsend


18

次のコードは私を驚かせました。私はそれは危険な落とし穴だと思います:実行するのは簡単で、デバッグするのも難しいです。

(1..5).each do |number|
  comment = " is even" if number%2==0
  puts number.to_s + comment.to_s
end

これは印刷します:

1
2 is even
3
4 is even
5

しかし、ブロックの前にcomment =何かを追加すると...

comment = nil
(1..5).each do |number|
  comment = " is even" if number%2==0
  puts number.to_s + comment.to_s
end

それから私は得る:

1
2 is even
3 is even
4 is even
5 is even

基本的に、変数がブロック内でのみ定義されている場合、その変数はブロックの最後で破棄され、nil反復のたびににリセットされます。それは通常あなたが期待することです。ただし、変数ブロックの前に定義されている場合、外部変数はブロック内で使用されるため、その値は反復間で永続的です。

1つの解決策は、代わりにこれを書くことです:

comment = number%2==0 ? " is even" : nil

多くの人(私を含む)は読みやすいので、「a = b if c」ではなく「」と書く傾向がありますa = (c ? b : nil)が、明らかに副作用があります。


4
(1..5)do | number; comment |で外側のスコープ変数をシャドウすることもできます。.....ここに読むにはstackoverflow.com/questions/1654637/...
Özgür

6
これは私には理にかなっているようです。このスコーピングは他の言語の典型であり、異なるのは構文だけです。
g。

ただし、a = (b if c)3項なしで希望する効果を得るために書くことができます。これはb if ccがfalseの場合にnil と評価されるためです。
Cameron Martin

16

super引数なしで呼び出すと、オーバーライドされたメソッドは、オーバーライドするメソッドと同じ引数で実際に呼び出されます。

class A
  def hello(name="Dan")
    puts "hello #{name}"
  end
end

class B < A
  def hello(name)
    super
  end
end

B.new.hello("Bob") #=> "hello Bob"

super引数なしで実際に呼び出すには、と言う必要がありますsuper()


3
場合B#helloがあるname = 42前にsuper、それは「42こんにちは」と言います。
Andrew Grimm、

14

ブロックとメソッドはデフォルトで最後の行の値を返します。putsデバッグ目的で最後にステートメントを追加すると、不快な副作用が発生する可能性があります



11

クラス変数、クラス属性、クラスメソッドを理解するのに多くの問題がありました。このコードは初心者を助けるかもしれません:

class A
  @@classvar = "A1"
  @classattr = "A2"
  def self.showvars
    puts "@@classvar => "+@@classvar
    puts "@classattr => "+@classattr
  end
end

A.showvars
  # displays:
  # @@classvar => A1
  # @classattr => A2

class B < A
  @@classvar = "B1"
  @classattr = "B2"
end

B.showvars
  # displays:
  # @@classvar => B1
  # @classattr => B2

A.showvars
  # displays:
  # @@classvar => B1   #Class variables are shared in a class hierarchy!
  # @classattr => A2   #Class attributes are not

1
はい、クラス変数は扱いにくい場合があります。ほとんどの経験豊富なRubyistは、それらを使わずに問題を解決する他の方法が通常あるため、それらを避けるのが賢明だと言っていると思います。一部の言語愛好家は、Rubyのクラス変数は言語レベルでは不十分に設計されているとさえ言うでしょう。
David J.

8

私が学んだことの1つは、演算子|| =を慎重に使用することでした。ブール値を扱う場合は特に注意してください。他のすべてが失敗し、「a」がnilのままである場合、私は通常「|」= bをキャッチオールとして使用し、「a」にデフォルト値を与えました。しかし、aがfalseでbがtrueの場合、aにはtrueが割り当てられます。


a = b if a.nil?またはを使用できます@a = b unless defined?(@a)
Andrew Grimm

8
  • ブロックは理解することが本当に重要であり、どこでも使用されています。

  • メソッドパラメータを括弧で囲む必要はありません。それらを使用するかどうかはあなた次第です。常に使うべきだと言う人もいます

  • スローとキャッチではなく、例外処理にレイズとレスキューを使用します。

  • 使用できます;が、1つの行に複数のものを配置する場合を除き、使用する必要はありません。


Ruby 1.8.6を超える予定がない場合は、括弧を必要なだけ無視してください。それ以外の場合は、おそらくそれらを使用する方が良いでしょう。
Mike Woodhouse

7

インスタンスメソッドクラスメソッドを含むミックスインで問題が発生しました。このコードは初心者を助けるかもしれません:

module Displayable
  # instance methods here
  def display
    puts name
    self.class.increment_displays
  end
  def self.included(base)
    # This module method will be called automatically
    # after this module is included in a class.
    # We want to add the class methods to the class.
    base.extend Displayable::ClassMethods
  end
  module ClassMethods
    # class methods here
    def number_of_displays
      @number_of_displays # this is a class attribute
    end
    def increment_displays
      @number_of_displays += 1
    end
    def init_displays
      @number_of_displays = 0
    end
    # this module method will be called automatically
    # after this module is extended by a class.
    # We want to perform some initialization on a
    # class attribute.
    def self.extended(base)
      base.init_displays
    end
  end
end

class Person
  include Displayable
  def name; @name; end
  def initialize(name); @name=name; end
end

puts Person.number_of_displays # => 0
john = Person.new "John"
john.display # => John
puts Person.number_of_displays # => 1
jack = Person.new "Jack"
jack.display # => Jack
puts Person.number_of_displays # => 2

最初は、これを行うだけで、インスタンスメソッドクラスメソッドの両方を持つモジュールを作成できると思いました。

module Displayable
  def display
    puts name
    self.class.increment_displays
  end
  def self.number_of_displays  # WRONG!
    @number_of_displays
  end
  [...]
end

残念ながら、number_of_displaysメソッドは「モジュールクラスメソッド」であるため、インクルードまたは拡張されることはありません。「モジュールインスタンスメソッド」のみをクラスに含める(インスタンスメソッドとして)か、クラスに拡張する(クラスメソッドとして)ことができます。これが、ミックスインのインスタンスメソッドをモジュールに入れ、ミックスインのクラスメソッドを別のモジュールに入れる必要がある理由です(通常、クラスメソッドを「ClassMethods」サブモジュールに入れます)。含まれている魔法のメソッドのおかげで、インスタンスメソッドとクラスメソッドの両方を1つの単純な "include Displayable"呼び出しに簡単に含めることができます(上記の例を参照)。

このミックスインは、クラスごとに各ディスプレイをカウントします。カウンターはクラス属性であるため、各クラスには独自の属性があります(派生クラスの@number_of_displaysカウンターは初期化されないため、Personクラスから新しいクラスを派生させると、プログラムはおそらく失敗します)。あなたは交換すること@number_of_displaysをすることによって @@ number_of_displaysて、グローバルカウンターにすることができます。この場合、各クラス階層には独自のカウンターがあります。グローバルで一意のカウンターが必要な場合は、おそらくそれをモジュール属性にする必要があります。

私がRubyを使い始めたとき、これらすべては私にとって間違いなく直感的ではありませんでした。

しかし、これらのミックスインメソッドのいくつかをきれいにプライベートまたは保護する方法はまだわかりません(displayおよびnumber_of_displaysメソッドのみをパブリックメソッドとして含める必要があります)。


7

範囲表記に注意してください。

(少なくとも、私が最初に行ったよりももっと注意を払ってください!)

0..10 (2ドット)と0...10(3ドット)には違いがあります。

Rubyをとても楽しんでいます。しかし、このドットドットとドットドットドットの違いは私を悩ませます。このような微妙な二重構文の「機能」は次のとおりだと思います。

  • ミスタイプしやすい
  • コードを見ながら目で見落としやすい

私のプログラムで壊滅的なオフバイワンのバグを引き起こすことができないはずです。


1
for (i=0; i<max; i++)andfor (i=0; i<=max; i++)
g

私は0..10と0 ... 10の違いは何であるかを見つけることを試みています。
Luis D Urraca

6

and」と「or」は、Rubyのより明白な「親」の1つであるPerlに対するうなずきだと思います(他の最も有名なものはSmalltalkです)。彼らの両方が(注意行動がどこから来るのである、実際には、割り当てより低い)はるかに低い優先順位を持ちより&&||使用する演算子どちらの演算子を使用する必要がありますか。

その他の注意点はすぐにはわかりません。

メソッド/関数は実際には呼び出しませんが、そのように見えます。代わりに、Smalltalkと同様に、オブジェクトにメッセージを送信します。だからmethod_missing本当にもっと似ていmessage_not_understoodます。

some_object.do_something(args)

に相当

some_object.send(:do_something, args) # note the :

シンボルは非常に広く使用されています。それは:、それらから始まるものであり、すぐには明らかではありません(まあ、私にはわかりませんでした)。

Rubyは、「アヒルのタイピング」に大きく関わっており、「アヒルのように歩き、アヒルのように鳴く...」という原則に従って、明示的な継承やミックスインの関係なしに、メソッドの共通サブセットを持つオブジェクトを非公式に置き換えることができます。


ありがとう。sendメソッドについて私が嫌いなことが1つあります。これにより、クラスの外部でもプライベートメソッドを呼び出すことができます。痛い。
MiniQuark 2008

1
@MiniQuark:それが私がsendメソッドについて気に入っていることです!
Andrew Grimm

6

attr_writeror attr_accessor(またはdef foo=)を使用してセッター(別名ミューテーター)を宣言する場合は、クラス内から呼び出すことに注意してください。変数は暗黙的に宣言されているので、インタープリターは常にfoo = bar、メソッドを呼び出すのではなく、fooという名前の新しい変数を宣言するように解決する必要があります。self.foo=(bar)ます。

class Thing
  attr_accessor :foo
  def initialize
    @foo = 1      # this sets @foo to 1
    self.foo = 2  # this sets @foo to 2
    foo = 3       # this does *not* set @foo
  end
end

puts Thing.new.foo #=> 2

これは、データベースのフィールドに基づいて定義されたアクセサーを取得するRails ActiveRecordオブジェクトにも適用されます。これらは@スタイルのインスタンス変数でもないため、これらの値を個別に設定する適切な方法は、self.value = 123またはを使用することself['value'] = 123です。


5

TimeクラスとDateクラスの違いを理解する。どちらも異なり、レールで使用しているときに問題が発生しました。Timeクラスは、標準のruby / railsライブラリにある他のTimeクラスライブラリと競合する場合があります。自分のRailsアプリで何が起こっているのかを理解するのに、個人的にかなりの時間がかかりました。後で、いつやったかを考えました

Time.new

それは私が知らない場所にある図書館を指していた。

正確に言いたいことがはっきりしない場合は申し訳ありません。他の人が同様の問題に直面した場合は、再度説明してください。


4

過去に私が\n気付いたのは、改行文字()のエスケープシーケンスが(他のものとともに)、単一引用符内の文字列でサポートされていないことです。バックスラッシュ自体はエスケープされます。エスケープが期待どおりに機能するには、二重引用符を使用する必要があります。


1
そして、それは他のどの言語とは異なりますか?
Robert Gamble

1つはJavaです。Javaの単一引用符は、文字列ではなく単一の文字を囲むためにのみ使用できます。
John Topley

1
これは、文字列に単一引用符を使用できる任意の言語と一致しており、そのために使用されています。
singpolyma 2008

@John:true、ただしJavaの '\ n'は改行文字のままです。
ジョーン

1
ただし、Javaでは単一引用符はchar型の値のみを作成します。文字列ではありません。それが違いです。
jmucchiello 2008

4
x = (true and false) # x is false

あなたが指摘したように、0と ''は真です。

メソッドとモジュール/クラスを同じ名前で持つことができます(メソッドが実際にオブジェクトに追加され、独自の名前空間を持つため、これは理にかなっています)。

多重継承はありませんが、一般的なメソッドを複数のクラスに追加するために「ミックスインモジュール」が頻繁に使用されます。


0 == true //脳内のcコンパイラが爆発している!!
ケニー

1
Rubyでは0 == trueはfalseになります。Rubyのオブジェクトはtrueであるため、0がtrueであることは理にかなっています。Cでは0はたまたまfalseと同じ表現を持っています。
ジュール、

Rubyでの条件では、唯一falsenilfalseです。他のすべては真の値です。
rubyprince

4

メソッドは再定義することができ、原因を発見するまで心を掻き立てることができます。(確かに、このエラーはおそらく、Ruby on Railsコントローラーのアクションが誤って再定義されたときに検出するのが少し難しいです!

#demo.rb
class Demo

  def hello1
    p "Hello from first definition"
  end

  # ...lots of code here...
  # and you forget that you have already defined hello1

  def hello1
    p "Hello from second definition"
  end

end
Demo.new.hello1

実行:

$ ruby demo.rb
=> "Hello from second definition"

しかし、警告を有効にして呼び出すと、その理由を確認できます。

$ ruby -w demo.rb
demo.rb:10: warning: method redefined; discarding old hello1
=> "Hello from second definition"

できれば警告を+100使用します。
Andrew Grimm、

3

ものに.lengthを使用することは常に良いことだと思います...サイズはほとんどすべてでサポートされており、Rubyには動的な型があるため、間違った型がある場合に.sizeを呼び出すと本当に奇妙な結果が得られます... NoMethodError:undefined method `length 'なので、Rubyでオブジェクトのサイズを呼び出すことは通常ありません。

私を二度以上噛みました。

また、オブジェクトにはIDがあることを忘れないでください。混乱を避けるために、IDまたはObject_IDを呼び出す変数を使用しないようにしています。UsersオブジェクトのIDが必要な場合は、user_idのような名前を付けるのが最善です。

ちょうど私の2セント


2

私はルビーが初めてで、最初のラウンドで、浮動小数点数/文字列を整数に変更することに関する問題にぶつかりました。私はフロートから始めて、すべてをf.to_intとしてコーディングしました。しかし、続けて同じ方法を文字列に使用すると、プログラムを実行するときに曲線がスローされました。

どうやら文字列にはto_intメソッドがありませんが、floatとintにはあります。

irb(main):003:0* str_val = '5.0'
=> "5.0"
irb(main):006:0> str_val.to_int
NoMethodError: undefined method `to_int' for "5.0":String
        from (irb):6
irb(main):005:0* str_val.to_i
=> 5


irb(main):007:0> float_val = 5.0
=> 5.0
irb(main):008:0> float_val.to_int
=> 5
irb(main):009:0> float_val.to_i
=> 5
irb(main):010:0>

最初は任意の括弧も投げました。あるコードとないコードを見ました。どちらのスタイルも受け入れられることを理解するのにしばらく時間がかかりました。


2

monkutの応答に関連して、Rubyのto_fooメソッドは、変換がどの程度厳密に行われるかを示唆しています。

のような短いものはto_ito_s遅延するように伝え、その形式で正確に表現できない場合でも、ターゲットの型に変換します。例えば:

"10".to_i == 10
:foo.to_s == "foo"

以下のようなより長い明示的な関数はto_intto_sオブジェクトがネイティブデータの型として表すことができることを意味します。たとえば、Rationalクラスはすべての有理数を表すため、を呼び出すことにより、Fixnum(またはBignum)整数として直接表すことができますto_int

Rational(20,4).to_int == 5

より長いメソッドを呼び出せない場合は、オブジェクトがその型でネイティブに表現できないことを意味します。

したがって、基本的には、変換時にメソッド名に遅延がある場合、Rubyは変換に遅延します。


1
ここで「怠惰」は正しい言葉ですか?
Andrew Grimm


1

ルビーハッシュの反復は、特定の順序で行われるとは限りません。(これはバグではなく、機能です)

Hash#sort 特定の注文が必要な場合に便利です。

関連質問:Rubyの1000ハッシュのキーと値のペアの配列が常に特定の順序になっているのはなぜですか?


4
これは、1.9のように有効ではありません:言語プログラミングルビーから「Ruby 1.9のでは、しかし、ハッシュ要素は、その挿入順に反復されている」
Özgür

0

これは私を一度怒らせました:

1/2 == 0.5 #=> false
1/2 == 0   #=> true

これはJava、C、C ++でもまったく同じように動作すると思います。
ラリー

それは面白いです、私はそれについてさえ考えていませんでしたが、irbを開いてこれを試してみると、それは理にかなっています。つまり、(1/2)はFixnumであり、(0.5)はFloatです。そして、Fixnim!= Floatであることを知っています。
DemitryT 2012年

2
@DemitryT単純な理由は、型に関係なく、と1/2評価され0、と等しくないこと0.5です。ただし、Rational(1, 2) == 0.5および1.0 == 1
Max Nanasy 2012

ここで普遍的な言語のしゃっくり。これは、rubyを初めて使用する人やプログラミングで知っておくべきことです。
dtc 2016年

0
1..5.each {|x| puts x}

動作しません。次のように、範囲を括弧で囲む必要があります

(1..5).each {|x| puts x}

だから、あなたが電話しているとは思わない5.each。これは、問題のように、優先順位の高い問題だと思いますx = true and false


代わりに括弧と呼びます。次に、コードに戻り値/優先順位の問題があるように見える場合は、とにかく括弧で囲む必要があります。だから、私にとって、この「ごちゃごちゃ」には特別なことは何もありません。ただし、すべての組み合わせの「落とし穴」を書き続けることはできますが、それは時間の無駄になります。率直に言って、これで期待どおりの結果が得られたとしても、括弧で囲むほうがいいと思います。
Özgür
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.