LoginSignup
5
5

More than 5 years have passed since last update.

ruby は インスタンス変数の確認に instance_variable_defined? を使う

Last updated at Posted at 2013-10-23

計算済みの値があるので、インスタンスメソッドを実行せずに値を返したい。簡易メモ化。

計算済みならインスタンス変数にセット、それ以外はインスタンスメソッドを実行、という挙動を実装してみる。

python のデータの持ち方はハッシュだから、名前を確認すればインスタンス変数があるか確認できる。
ruby だとどうやるのかと思ったら、instance_variable_defined? というメソッドがあった。

class A
  def a=(a)
    @a = a
  end

  def a
    @a
  end
end

class B
  def a=(a)
    @a = a
  end

  def a
    return @a if instance_variable_defined?(:@a)
    "b"
  end
end

require 'minitest/unit'
require 'minitest/autorun'

class ATest < MiniTest::Unit::TestCase
  def test_undefined_instance_variable_is_nil
    a = A.new
    assert_equal nil, a.a
  end
end

class BTest < MiniTest::Unit::TestCase
  def test_undefined_instance_variable_is_constant
    b = B.new
    assert_equal "b", b.a
  end

  def test_gettable_instance_variable_after_set
    b = B.new
    b.a = "a"
    assert_equal "a", b.a
  end
end
`Run options: --seed 38869

# Running tests:

...

Finished tests in 0.001566s, 1915.7088 tests/s, 1915.7088 assertions/s.

3 tests, 3 assertions, 0 failures, 0 errors, 0 skips

名前が長いということは、使用を推奨されないということなのだろうか?

python は hasatter で何でもイケる。

import unittest

class A(object):
    @property
    def a(self):
        return self._a

    @a.setter
    def a(self, a):
        self._a = a

class B(object):
    @property
    def a(self):
        if hasattr(self, "_a"):
            return self._a
        return "b"

    @a.setter
    def a(self, a):
        self._a = a

class ATest(unittest.TestCase):
    def test_undefined_instance_variable_is_error(self):
        a = A()
        self.assertRaises(AttributeError, lambda : a.a)

class BTest(unittest.TestCase):
    def test_undefined_instance_variable_is_constant(self):
        b = B()
        self.assertEqual("b", b.a)

    def test_gettable_instance_variable_after_set(self):
        b = B()
        b.a = "a"
        self.assertEqual("a", b.a)

unittest.main()
5
5
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
5