0

以下の「クレイジーネス」への実用的なアプリケーションはありますか?

これは、ted常に自分自身を世界に戻すことができる方法のようであり、人々はted、特定の行動と特定の年齢になることを期待している人と話していると思うでしょう...しかし、彼はそのように行動していません.彼は自分自身を描写し、誰かに自分の年齢について嘘をついています.

オブジェクトが返されたときにどのような「トリック」が可能であり、そのオブジェクトが何を表し、何ができるかを確認します...しかし、実際には、そのオブジェクトは別の方法で動作し、戻る前に他のことができました。

class Person

  def age
    21
  end

  def who_am_i?
    puts "I am #{self} / #{object_id} and I am #{age} years old"
    self
  end
end


ted = Person.new

def ted.singleton_who_am_i?       

    class << self
      def age
        0
      end
    end

    puts "I am #{self} / #{object_id} and I am #{age} years old"
    self
end

puts ted.who_am_i? == ted.singleton_who_am_i?



>> I am #<Person:0x100138340> / 2148123040 and I am 21 years old
>> I am #<Person:0x100138340> / 2148123040 and I am 0 years old
>> true
4

2 に答える 2

0

Ruby は、実行時にオブジェクトにコードを挿入できる非常に動的な言語です。これにはいくつかの良い用途がありますが、コードをデバッグして理解するのが非常に難しくなる可能性もあります。

オブジェクトにクエリを実行してそのオブジェクトを変更するメソッドは、完全に直観に反しています。オブジェクトを変更するために who_am_i を呼び出すとは誰も期待しません。

一方、そのようなメソッドを置き換えることで、クラスの単体テストを非常に簡単にすることができます。

クラスがさまざまな年齢でどのように動作するかをテストしたい場合は、テストの前にそのようなコードを挿入できます。

于 2012-04-26T06:10:20.363 に答える
0

http://andrzejonsoftware.blogspot.ca/2011/02/dci-and-rails.html

DCI では、データ モデルは、使用されるコンテキストに基づいてさまざまなタイプの動作を取得します。通常、これは object.extend で行われますが、メタクラスを利用して上記で行っていることとほぼ同じです。

もう 1 つの例 (そしておそらくそのように動作する理由) は、Ruby でのクラスの動作です。あなたが言うなら

class Foo
end

と言っているのと同じことです

Foo = Class.new
end

つまり、クラス Class の新しいインスタンスを定数に割り当てています。そのクラスでメソッドを定義する場合、それをクラス Class のすべてのインスタンスに適用するのではなく、定義しているクラスにのみ適用する必要があります。だからあなたが言うとき

class Foo
  def self.bar
  end
end

それはまさに言っていることです

class Foo
end

def Foo.bar
end

これは、質問で話しているのとまったく同じプリンシパルです

(わかりにくかったらすいません)

于 2012-04-26T06:08:04.083 に答える