2015-08-27 14 views
6

Come accennato in this answer, in Ruby 2.1 o versioni successive, questo codice:È possibile ispezionare dinamicamente l'ambito di visibilità del metodo (privato/pubblico/protetto)?

class SimpleTest 
    private 

    define_method :foo do 
    42 
    end 
end 

definiranno foo come un metodo privato di SimpleTest casi. (In Ruby 2.0 e precedenti non sarà privato.) Tuttavia, sto cercando di fare qualcosa di un po 'meno banale. Mi piacerebbe definire un DSL che le classi possano estendere e vorrebbe i metodi che il DSL definisce internamente per rispettare la visibilità privata/protetta del contesto chiamante. Che non può essere chiaro, ecco un esempio:

module Dsl 
    def has_a(name) 
    define_method name do 
     42 
    end 
    end 
end 

class Test 
    extend Dsl 

    private 

    has_a :thing 
end 

Come scritto, che il codice definisce un metodo di pubblico thing su Test istanze. Invece, mi piacerebbe che has_a fosse in grado di riflettere sulla visibilità del metodo in cui è stato chiamato (private in questo caso) e definire thing sotto la stessa visibilità del metodo.

Non ho familiarità con il codice sorgente di Ruby C, ma ho dato una rapida occhiata e ho trovato this function che sembra possa fare ciò che voglio, ma non penso sia accessibile da Ruby. (Sembra essere utilizzato solo here.) Ho anche guardato la documentazione per define_method (dal momento che il primo esempio funziona come desiderato) here e sembra che la variabile noex dichiarato e impostare qui:

int noex = NOEX_PUBLIC; 
const NODE *cref = rb_vm_cref_in_context(mod, mod); 

if (cref) { 
    noex = (int)cref->nd_visi; 
} 

potrebbe essere la valore che voglio, ma ancora non so come lo otterrei in Ruby, o anche se sarebbe in grado di riflettere sull'ambito di chiamata (in Test). Supponendo di avere la visibilità, potrei semplicemente chiamare private name (o protected name) dopo la chiamata define_method all'interno di has_a se non è stato chiamato in un contesto public.

Pensieri? C'è un modo per farlo, o sono sfortunato?

risposta

1

penso che questa domanda ha una risposta simile a quello che stai cercando: https://stackoverflow.com/a/28075865/5129208

Sembra che l'autore del fatto che un modulo personalizzato per ottenere il comportamento che stai cercando.

+0

Grazie per avermi segnalato. Non l'ho visto quando ho cercato prima di chiedere. È una soluzione interessante, anche se preferirei non dover anteporre qualcosa a 'Module'. – rmacklin

Problemi correlati