Diamo un'occhiata a come l'incarico costante funziona internamente. Il codice che segue è estratto da un tarball sorgente di ruby-1.9.3-p0. In primo luogo guardiamo la definizione delle istruzioni VM setconstant
(che viene utilizzato per assegnare le costanti):
# /insns.def, line 239
DEFINE_INSN
setconstant
(ID id)
(VALUE val, VALUE cbase)
()
{
vm_check_if_namespace(cbase);
rb_const_set(cbase, id, val);
INC_VM_STATE_VERSION();
}
Nessuna possibilità di inserire un gancio in vm_check_if_namespace
o INC_VM_STATE_VERSION
qui. Quindi guardiamo rb_const_set
(variable.c 1886), la funzione che viene chiamata ogni volta che una costante viene assegnata:
# /variable.c, line 1886
void
rb_const_set(VALUE klass, ID id, VALUE val)
{
rb_const_entry_t *ce;
VALUE visibility = CONST_PUBLIC;
# ...
check_before_mod_set(klass, id, val, "constant");
if (!RCLASS_CONST_TBL(klass)) {
RCLASS_CONST_TBL(klass) = st_init_numtable();
}
else {
# [snip], won't be called on first assignment
}
rb_vm_change_state();
ce = ALLOC(rb_const_entry_t);
ce->flag = (rb_const_flag_t)visibility;
ce->value = val;
st_insert(RCLASS_CONST_TBL(klass), (st_data_t)id, (st_data_t)ce);
}
ho rimosso tutto il codice che non è stato anche chiamato la prima volta è stato assegnato un costante all'interno di un modulo. Ho quindi esaminato tutte le funzioni chiamate da questo e non ho trovato un singolo punto in cui potremmo inserire un gancio dal codice Ruby. Ciò significa che la dura verità è, a meno che non mi sia sfuggito qualcosa, che ci sia il modo no per agganciare un incarico costante (almeno in MRI).
Aggiornamento
per chiarire: La classe anonima non non magicamente ottenere un nuovo nome, non appena viene assegnato (come indicato correttamente nella risposta di Andrea). Piuttosto, il nome costante insieme all'ID oggetto della classe è memorizzato nella tabella di ricerca costante interna di Ruby. Se, successivamente, viene richiesto il nome della classe, ora può essere risolto con un nome appropriato (non solo Class:0xXXXXXXXX...
).
Quindi il meglio che puoi fare per rispondere a questo compito è controllare lo name
della classe in un ciclo di un thread di lavoro in background fino a quando non è nil
(che è un enorme spreco di risorse, IMHO).
Domanda molto interessante. –
AFAIK non esiste ancora alcun hook per le assegnazioni di variabili, costante o altro ([vedere qui per la stessa domanda molto tempo fa] (http://www.ruby-forum.com/topic/65720)). Globale, si. –