0

Rubyがこれらのクラスをインスタンス変数ではなくローカル変数内にインスタンス化/保存するように強制するのはなぜですか?

コードを変更して機能させる前は、次のようになっています。

require 'test/unit'
require 'converter'

class TestConverter < Test::Unit::TestCase

  @cv = Convert.new

  def test_celsius
    assert_equal(100.0, @cv.celsius(212))
    assert_equal(0.0, @cv.@celsius(32))
  end

  def test_fahrenheit
    assert_equal(212.0, @cv.fahrenheit(100))
    assert_equal(32.0, @cv.fahrenheit(0))
  end

end

このエラーをスローしました:

% ruby -I. converter_test.rb                                                  ✭
Run options: 

# Running tests:

EE

Finished tests in 0.000616s, 3246.7638 tests/s, 0.0000 assertions/s.

  1) Error:
test_celsius(TestConverter):
NoMethodError: undefined method `celsius' for nil:NilClass
    converter_test.rb:9:in `test_celsius'

  2) Error:
test_fahrenheit(TestConverter):
NoMethodError: undefined method `fahrenheit' for nil:NilClass
    converter_test.rb:14:in `test_fahrenheit'

2 tests, 0 assertions, 0 failures, 2 errors, 0 skips

各メソッド内でクラス(Convert)をインスタンス化してみることにし、成功しました。

require 'test/unit'
require 'converter'

class TestConverter < Test::Unit::TestCase

  #@cv = Convert.new
  #instantiated the class in each method instead of here

  def test_celsius
    cv = Convert.new
    assert_equal(100.0, cv.celsius(212))
    assert_equal(0, cv.celsius(32))
  end

  def test_fahrenheit
    cv = Convert.new
    assert_equal(212, cv.fahrenheit(100))
assert_equal(32, cv.fahrenheit(0))
end
end
ddouglas@coders:~/Develop/davincicoders$ ruby -I. converter_test.rb
Run options: 

# Running tests:

..

Finished tests in 0.001894s, 1055.9149 tests/s, 2111.8298 assertions/s.

2 tests, 4 assertions, 0 failures, 0 errors, 0 skips

最初の試行でRubyがインスタンス変数をオブジェクトとして認識しないのはなぜですか?

4

3 に答える 3

3

@cvテストの外側で宣言すると、インスタンス変数 for になりますTestConverter- のインスタンスではありませんTestConverter!

おそらく、これを回避する最も簡単な方法は、クラス変数にすることです: @@cv.

まだ混乱している場合は、次の例を検討してください。

class Foo
  @x = 3
  def initialize
    @y = 4
  end
end

puts Foo.instance_variables
puts Foo.new.instance_variables
于 2012-06-25T21:47:45.700 に答える
2

これは、他の言語に期待するものとは異なる動作をするため、(私を含む) 人々を混乱させることがよくあります。Javaの例で説明しようとします:

class Foo
  @bar = 42
end

と同等ではありません

 public class Foo {
      private int bar = 42;
 }

しかし、実際にはほぼ同等です

 public class Foo {
      private static int bar = 42;
 }

IRB で試してみてください。

class Foo
  attr_accessor :bar
  @bar = 42
  class << self
    attr_accessor :bar
  end
end
Foo.bar # => 42
Foo.new.bar # => nil

では、これはなぜですか?Ruby では、すべてがオブジェクトです。したがって、任意のクラス (例: Foo) はクラスのインスタンスですClass(わかりにくいと思いますが)。間にあるものはすべて、クラスclass Foo; endのインスタンスのスコープで実行されます。FooClass

これは決して完全な説明ではないので、詳細をよく読む必要があります。

于 2012-06-25T22:11:37.320 に答える
0
assert_equal(0.0, @cv.@celsius(32))

これはいけませんか

assert_equal(0.0, @cv.celsius(32))
于 2012-06-25T21:42:15.967 に答える