2

以下はThe Rspec Bookからのものです。なぜmessages << messageindef putsが でないのか不思議です@messages << message。それ||= []がメモ化であることは理解していますし、それ@messagesがインスタンス変数であることも理解しています。では、同じクラスで使用する必要がありますか?それともタイプミスですか?

class Output
  def messages
    @messages ||= []
  end

  def puts(message)
    messages << message
  end
end

def output
  @output ||= Output.new
end

Given /^I am not yet playing$/ do
end

When /^I start a new game$/ do
  game = Codebreaker::Game.new(output)
  game.start
end

Then /^I should see "([^"]*)"$/ do |message|
  output.messages.should include(message)
end
4

3 に答える 3

5

作成者は遅延オブジェクト作成を選択しました。メッセージはコンストラクターではなく、getter メソッドで作成されます。@messages に直接アクセスしない限り、nil 例外は発生しません。

class Output
  def messages
    @messages ||= []
  end

  def puts(message)
    # If i was to use the variable @messages at this point,
    # i would get a nil exception, the array was never allocated.
    # Using the getter ensures that the array is allocated.
    messages << message
  end
end

オブジェクトの作成を怠る必要がない場合は、次の方法で同じクラスを作成できます。

class Output
  attr_reader :messages

  def initialize(message)
    @messages = []
  end

  def puts(message)
    # messages was created when this object was initialized,
    # thus it is perfectly safe to use here.
    @messages << message
  end
end
于 2013-10-20T11:30:57.157 に答える
5

あなたの混乱は@messages変数とmessagesメソッドの間だと思います

class Output
  def messages
    @messages ||= []
  end

  def puts(message)
    messages << message #=> here `messages` refer to the method above
  end
end

ここに簡単な例があります

class Output
  def m
    @messages ||= []
  end

  def puts(message)
    m << message #=> method `m`
  end
end

v = Output.new
v.puts "blah"
v.m #=> ["blah"]

例 2 (より明確にするため)

class Output
  def m
    @messages ||= []
  end

  def puts(message)
    m << message #=> here `m` refer to the method above
  end

  def show_at_messages_variable
    @messages
  end
end

v = Output.new
v.puts "blah"
v.show_at_messages_variable #=> ["blah"]
于 2013-10-20T11:24:11.127 に答える
5

なぜなら

def puts(message)
  messages << message
end

次に呼び出します

def messages
  @messages ||= []
end

まだ存在しない場合は||= []、空の配列を割り当てます。@messagesそのため、直接puts(message)使用しません。@messages

編集:@messages << message直接行う場合@messages、その時点ではまだ存在しない可能性があります。そのため、代わりに通過しmessagesます。

于 2013-10-20T11:18:00.620 に答える