2
# encoding: utf-8
class Person
  attr_reader :short_name
  def initialize(short_name)
    @short_name = short_name
  end

  def greeting_line
    short_name = short_name.downcase
    "Hello #{short_name}"
  end
end

person = Person.new("MS. LEE")

puts person.short_name  => "MS. LEE"
puts person.greeting_line => NoMethodError: undefined method `downcase' for nil:NilClass

(short_name = short_name) により short_name が nil になるため、「short_name = short_name.downcase」で例外が発生します。

右側の「short_name」がインスタンスメソッド「short_name」から値を取得していないのはなぜですか?

4

4 に答える 4

3

あなたが言う時

var = value

メソッドがあり、定義されている場合でも、常にローカル変数を参照します。(あなたの場合、によって定義されたメソッドがありますが、定義していません。)varvarvar=short_nameattr_readershort_name=

これにはいくつかの方法があります。インスタンス変数を直接使用できます。

@var = value

var=または、明示的なselfレシーバーでメソッドを使用できます。

self.var = value

var=この 2 番目の形式は、明示的に、または または を使用してメソッドが定義されattr_accessorている場合にのみ機能しますattr_writer

今、あなたが何かをするとき

foo = foo

これにより、常にfoo左側にローカル変数が導入されます。ruby がfooの右側を見ると、スコープ内にあるため、ローカル変数=に解決されます。したがって、これは常にデフォルト値に戻るだけです。 foofoofoonil

于 2012-09-27T21:54:01.320 に答える
1

あなたの場合、greeting_lineスコープ short_name はインスタンスメソッドではなくローカル変数を指していますshort_name。この例を機能させるには、使用する必要がありますself.short_name(これにより、ルビーにインスタンスメソッドを使用するように指示されます)

def greeting_line
 short_name = self.short_name.downcase
 "Hello #{short_name}"
end
于 2012-09-27T21:53:39.743 に答える
0

short_name を参照するときに @ を忘れただけです

@short_name

インスタンス変数です

short_name

greeting_line 関数のスコープにバインドされたローカル変数です

これを試して:

def greeting_line
  short_name = @short_name.downcase
  "Hello #{short_name}"
end
于 2012-09-27T20:40:18.213 に答える
0

以下を使用する必要があります。

  attr_accessor :short_name

attr_readerではありません。

attr_reader は、クラスで次のメソッドを生成します。

def short_name
  @short_name
end

attr_accessor は次のメソッドも生成します。

def short_name=(val)
  @short_name = val
end

short_name はローカル変数であるため、自由に設定できます。

これは、ruby での attr_reader、attr_writer、および attr_accessor ステートメントを示す素晴らしいブログ投稿です。

于 2012-09-27T20:41:19.547 に答える