Ho riscontrato un problema con le istanze mancanti e gli errori nilClass durante la chiamata ai percorsi. Dopo aver esplorato la fonte, sembra che la chiamata generate_method crei fondamentalmente un nuovo metodo usando il blocco del metodo iniziale.Come aggirare la mancanza di contesto nei metodi di route di Sinatra
get "/" do
@some_local_instance.do_something()
end
Così nel metodo sopra ci potrebbero benissimo essere una variabile locale all'interno di tale classe denominata some_local_instance, tuttavia quando il meccanico è effettivamente valutata non ha alcun contesto da cui è stato definito il metodo, così sarà sicuro.
Il motivo che mi chiedo è perché, come parte del mio scritto ho classi esterne che vengono caricati quando Sinatra è caricato che registrano i percorsi e quando questi percorsi sono chiamati ho bisogno di accedere ad alcune variabili locali su queste classi. Un esempio potrebbe essere:
class SomeRouteClass
def initialize(sinatra, calculator)
@calculator = calculator
@sinatra = sinatra
end
def setup_routes
@sinatra.get "/add" do
return @calculator.add(1,1)
end
end
end
class Calculator
def add(a,b)
return a+b;
end
end
sinatra = Sinatra.new
calculator = Calculator.new
routing_class = SomeRouteClass.new(sinatra, calculator)
routing_class.setup_routes
sinatra.run!
Perdonate eventuali errori di ortografia/sintassi Questo è solo un esempio veloce, ma come si può vedere una classe registra percorsi e quando questo percorso viene colpito restituisce un valore generato da un'istanza della calcolatrice ci sono voluti quando è stato istanziato.
Problema che ho è che in questo esempio quando provo ed eseguo il percorso/add mi dice che @calculator è un nilClass, e credo che sia dovuto al modo in cui Sinatra prende solo il blocco del codice senza contesto. Questo sembra perfetto per qualsiasi semplice rendering di template, ma se hai bisogno di fare qualcosa di più stravagante, o vuoi mantenere il tuo codice modulare non usando statica e singleton, non sembra che tu abbia alcun modo per aggirare questo ...
Are le mie supposizioni sono corrette qui? e se è così, c'è un modo per mantenere il contesto come sembra che mi costringa a scrivere codice cattivo e difficile da mantenere se devo scrivere tutto come statica e singleton per interagire da una rotta.
== Modifica ==
hanno ristrutturato la questione e contenuti per riflettere più accuratamente il problema reale, ora che ho una comprensione più solida della biblioteca.
Dopo guardando attraverso la fonte un po ', sembra che si limita a copiare e incollare il metodo che viene utilizzato con una rotta in un nuovo metodo usando define_method. Quindi non esiste un contesto al di fuori di quel metodo ... il che implica che l'unico modo per aggirare sarebbe quello di rendere tutto statico, che sembra solo sbagliato ... poiché è più difficile cambiarlo e testarlo in questo modo ... Potrei essere completamente sbagliato su ciò che sta facendo però come Ruby è ancora un nuovo linguaggio per me. – Grofit
Ho cercato di usare il modello di oggetto const per aggirare questo, ma questo sta ancora rendendo le cose DAVVERO sgradevoli come TUTTO deve essere statico perché questo funzioni ... c'è un motivo per cui copiano il metodo body in un nuovo metodo quindi perde tutto il contesto? come non riesco a vedere alcun beneficio ad esso, solo inconvenienti ... anche se ancora una volta sono nuovo a questo, quindi potrebbe non comprendere appieno alcune complicazioni che richiede questo. L'unica cosa che posso pensare è che l'oggetto body del metodo può essere ripulito o il metodo può essere aggiornato o rimosso dall'istanza prima che venga chiamato, tuttavia ciò non sembra probabile – Grofit