2

さて、このパズルのステップ 2 を解こうとしていたのですが、問題が発生しています。私の問題は、インスタンス変数にアクセスしようとし(@name)たり、クラスのメソッドを呼び出したりしようとしたとき(name getter)です.rubyは、未定義のローカル変数を教えてくれます. 私には、これは範囲の問題のように思えます。アクション名とブロックがパラメーターとして与えられたときに問題が発生します。私が信じているインスタンス変数にシングルトンが正常に追加されていますが、それを呼び出すと、「名前」が未定義のローカル変数であることがRubyに通知されます。何か案は?他の方法でより効率的に機能をエミュレートする方法はありますか?

ここに私のDog.rbクラスがあります:

class Dog
  MSGS = {:dance => 'is dancing', :poo => 'is a smelly doggy!', :laugh => 'finds this hilarious!'}
  attr_accessor :name

  def initialize(name)
    @name = name
  end

  def can(*actions)
    actions.each do |action|
      self.instance_eval do
        if block_given?
          define_singleton_method action do
            yield
          end
        else
          define_singleton_method(action) do
            name + ' ' + MSGS[action]
          end
        end
      end
    end
  end

  def method_missing(method_name,*args)
    name + " can't " + method_name.to_s
  end
end

パズルの Dog_Game.rb は次のとおりです。

require './dog'

lassie, fido, stimpy = %w[Lassie Fido Stimpy].collect{|name| Dog.new(name)}
lassie.can :dance, :poo, :laugh
fido.can(:poo){"#{name} is just wayyyy too smelly."} #name here is the source of the problem
stimpy.can :dance
stimpy.can(:cry){"#{name} cried AHHHH"}

p lassie.dance
p lassie.poo
p lassie.laugh
puts
p fido.dance
p fido.poo
p fido.laugh
puts
p stimpy.dance
p stimpy.poo
p stimpy.laugh
p stimpy.cry
4

2 に答える 2

1

define_singleton_methodメソッドが必要な場合は、ブロックを渡します。

def can(*actions, &block)
  actions.each do |action|
    if block_given?
      define_singleton_method(action, block)
    else
      define_singleton_method(action) { "#{name} #{MSGS[action]}" }
    end
  end
end

これはあなたが期待するものを出力します。

(Delta が最初にスティンピーを証明するcryのは、他のインスタンスではなく、cryそれぞれの呼び出しです。)

Stimpy is dancing
Stimpy can't poo
Stimpy can't laugh
Stimpy cried AHHHH

Lassie is dancing
Lassie is a smelly doggy!
Lassie finds this hilarious!
Lassie can't cry

Fido can't dance
Fido is just wayyyy too smelly.
Fido can't laugh
Fido can't cry
于 2012-12-29T02:38:31.120 に答える
1

1: 醜いメソッドを作成します:

self.instance_eval {} == define_singleton_method(callback, &block)

どちらかを使用する必要がありますが、両方を使用することはできません。

2:使用するとスコープが変わるため

self.instance_eval do 
   #coding
end

変数 :name は使用できないので、define_singleton_method を使用してください!

すみません、私の英語はとても下手です!

于 2012-12-29T03:19:31.350 に答える