Techioz Blog

ハッシュがnilの場合、キーを設定するにはどうすればよいですか?

概要

タイトルをキーとして使用して書籍オブジェクトをハッシュに保存しています。本がすでにハッシュに含まれている場合は、別のメソッドを呼び出しているので、 key? を使用して本がハッシュに含まれているかどうかを確認します。方法。ただし、エラーが発生します。

     if self.bookshelf.key?(title)

self.bookshelf が nil なのはなぜですか?コードで使用している方法では、この時点ではまだ何も追加していないことに注意してください。そのため、ランタイムのこの時点でキーが存在するかどうかのチェックは意味がありません。ただし、必要になります。後で確認するために。したがって、そのコードをコメントアウトして実行すると、

self.bookshelf[title] = book

わかりました:

クラスの新しいメソッドで新しいハッシュを作成すると、本棚が nil になるのはなぜですか?

class Shelf
  attr_accessor :bookshelf
  def new
    bookshelf = Hash.new()
  end 
  def add_book(title, book)
    if self.bookshelf.key?(title)
      #do something 
    else
      self.bookshelf[title] = book
    end 
  end 
end 

解決策

Bookshelf = (self なし) は、別のメソッドのスコープに設定されていないローカル変数のみを設定します。代わりに、 @bookshelf または (attr_accessor を使用する場合) self.bookshelf = を使用する必要があります。自分自身に注意してください。 attr_accessor によって作成された getter メソッドを介して値を読み取る場合は必要ありません。

さらに、新しいインスタンスを作成するために Ruby で新しいメソッドを実装する必要はありません。代わりに、new を呼び出すときに呼び出されるメソッドの 1 つであるInitialize を実装します。

これはうまくいくはずです:

class Shelf
  attr_accessor :bookshelf

  def initialize
    self.bookshelf = {} # `{}` is idiomatic Ruby for `Hash.new`
  end 

  def add_book(title, book)
    if bookshelf.key?(title)
      puts "Title '#{title}' is already in the bookshelf"
    else
      bookshelf[title] = book
    end 
  end 
end 

shelf = Shelf.new
shelf.add_book('Book 1', '...')
shelf.add_book('Book 2', '...')

shelf.add_book('Book 1', '...')
#=> Title 'Book 1' is already in the bookshelf