Domanda

Quindi, voglio definire un metodo singleton per un oggetto, ma voglio farlo usando una chiusura.

Ad esempio,

def define_say(obj, msg)
  def obj.say
    puts msg
  end
end

o = Object.new
define_say o, "hello world!"
o.say

Questo non funziona perché la definizione di un metodo singleton tramite " def " non è una chiusura, quindi ottengo un'eccezione che "msg" è una variabile o un metodo indefinito.

Quello che vorrei fare è qualcosa come usare il metodo " define_method " metodo nella classe Module, ma per quanto ne so, questo può essere usato solo per definire un metodo su una classe ... ma voglio un metodo Singleton ...

Quindi, mi piacerebbe scriverlo in questo modo:

def define_say(obj, msg)
  obj.define_singleton_method(:say) {
    puts msg
  }
end

Qualcuno sa come posso raggiungere questo obiettivo senza dover creare un metodo per archiviare un Proc e quindi utilizzare Proc in un metodo singleton? (fondamentalmente, voglio un modo pulito e non confuso di farlo)

È stato utile?

Soluzione

Ecco una risposta che fa quello che stai cercando

def define_say(obj, msg)
  # Get a handle to the singleton class of obj
  metaclass = class << obj; self; end 

  # add the method using define_method instead of def x.say so we can use a closure
  metaclass.send :define_method, :say do
    puts msg
  end
end

Utilizzo (incolla da IRB)

>> s = "my string"
=> "my string"
>> define_say(s, "I am S")
=> #<Proc:0xb6ed55b0@(irb):11>
>> s.say
I am S
=> nil

Per maggiori informazioni (e una piccola libreria che la rende meno disordinata) leggi questo:

http://viewsourcecode.org/why/hacking/seeingMetaclassesClearly.html

A parte questo, se sei un programmatore di rubini e NON L'hai letto, vai a farlo ora ~!

Altri suggerimenti

Oggetto # define_singleton_method è stato aggiunto a ruby-1.9.2 a proposito:

def define_say(obj, msg)
  obj.define_singleton_method(:say) do
    puts msg
  end
end
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top