Rails configure?

Mmmm, allora: avrei bisogno che qualcuno mi spiegasse il funzionamento
delle configurazioni di Rails, ad esempio:

MyApp::Application.configure do
config.cache_classes = true
config.consider_all_requests_local = false
config.action_controller.perform_caching = true
config.action_dispatch.x_sendfile_header = “X-Sendfile”
…

end

Come vengono realizzate?
Spero sia abbastanza chiaro cosa non capisco…
Vorrei utilizzarle in un progetto…

Grazie infinite,
iwan

2012/3/1 Iwan B. [email protected]:

end

Come vengono realizzate?
Spero sia abbastanza chiaro cosa non capisco…

onestamente non si capisce tanto :slight_smile:
Intendi come fare una cosa in questo stile? Per cui tu possa fare, e.g.

Game.configure do
config.difficulty = :hard
config.players = 10
end

?
Se cos, sostanzialmente devi solo guardare il metodo #instance_eval
(o #class_eval, #module_eval a seconda di quel che preferisci).

Io personalmente preferisco lo stile con parametro esplicito.

–
twitter: @riffraff
blog (en, it): www.riffraff.info riffraff.blogsome.com
work: cascaad.com circleme.com

Volevo vedere e capire come viene realizzata la lettura della parte
contenuta nel blocco.
Vedo ad esempio che nel suo esempio Gabriele fa uso della variabile
‘config’ (in config.difficulty = :hard), mentre Luca non la usa…

Grazie!

Il fatto che nel tuo esempio originale la variabile config non venga
passata nel blocco significa che o definita appena prima del blocco
oppure un metodo che in scope, oppure ancora che un metodo della
classe/modulo/whatever che esegue l’eval del blocco.
Nel mio esempio, la classe a definire direttamente un’implementazione
di
method_missing, mentre nel “tuo” direi che questo oggetto “config” o fa
la
stessa cosa oppure le varie propriet sono effettivamente definite
esplicitamente.

Utilizzo fatto da poco del metodo in questione:
https://github.com/adhearsion/adhearsion/blob/develop/lib/adhearsion/menu_dsl/menu_builder.rb

Questa classe parsa un blocco del tipo che vedi sotto “Current
Implementation” qui: http://polysics.github.com/2011/12/01/menu-dsl.html

Luca

Io l’ho implementato anche in maniera completamente implicita, come:

App.config do
domain ‘foo.com’, :https => false
port ‘8976’
end

L’ho fatto cos principalmente per requisiti (me l’hanno chiesto), usando
class_eval e method_missing, ma col senno di poi l’oggetto esplicito e
le
assegnazioni danno un risultato molto pi pulito.

Luca

2012/3/2 Iwan B. [email protected]:

Volevo vedere e capire come viene realizzata la lettura della parte
contenuta nel blocco.
Vedo ad esempio che nel suo esempio Gabriele fa uso della variabile
‘config’ (in config.difficulty = :hard), mentre Luca non la usa…

fondamentalmente lo stesso, nel mio caso avresti fatto una cosa cos:
class App
Config = Struct.new(:foo, :bar, :baz)
attr_reader :config
def initialize
@config = Config.new
end
def configure_with_implicit_config(&block)
instance_eval &block
end
end

MyApp = App.new

MyApp.configure_with_implicit_config do
#questo codice eseguito nel contesto dell’oggetto MyApp, e accede
a @config tramite il suo accessor, come se le righe avessero

“self.” davanti

config.foo= ‘foo!’
config.bar= ‘bar!’
end

p MyApp

=> #<App:0x0000010086c440 @config=#<struct App::Config foo=“foo!”,
bar=“bar!”, baz=nil>>

oppure puoi passare config come parametro al blocco, che per me meglio:

def configure_with_explicit_config
yield config
end

MyApp.configure_with_implicit_config do |config|

nessun cambio di contesto

config.foo= ‘foo!’
config.bar= ‘bar!’
end

Il modo in cui fa luca usa come contesto l’oggetto config stesso, cio
sarebbe come fare

def configure_with_even_more_implicit_config(&block)
config.instance_eval(&block)
end

ma a questo punto non puoi usare la sintassi cos:

MyApp.configure_with_even_more_implicit_config do
foo = ‘foo!’
bar = ‘bar!’
end

perch ruby interpreta l’assegnamento come se fossero variabili
locali, non come se tu stessi invocando “self.foo=”
Infatti se diventi esplicito funziona:

MyApp.configure_with_even_more_implicit_config do

siccome hai fatto config.instance_eval qui self corrisponde a

config
self.foo = ‘foo!’
self.bar = ‘bar!’
end

e a questo punto il trick standard, come ha fatto luca, di non usare
la sintassi “=” ma di usare una sintassi che forzi ruby a interpretare
le cose come metodi, cio:

MyApp.configure_with_even_more_implicit_config do

siccome sembra un’invocazione di un

metodo “qualcosa” ruby lo interpreta cos
foo ‘foo!’
bar ‘bar!’
end

Per usare questo trick devi definirti i metodi per i vari attributi
(non puoi usare una Struct come ho fatto io che li definisce da se, n
attr_accessor), oppure lo stesso approccio di Luca, usi
#method_missing e viene una cosa cos

class App
class Config
def method_missing(name, *arguments, &block)
if arguments.size != 1 && block.nil?
super
else
instance_variable_set “@#{name}”, arguments.first
end
end
end
attr_reader :config
def initialize
@config = Config.new
end
def configure_with_more_implicit_config(&block)
config.instance_eval &block
end
end

MyApp = App.new

MyApp.configure_with_more_implicit_config do
foo ‘foo!’
bar ‘bar!’
end

p MyApp

–
twitter: @riffraff
blog (en, it): www.riffraff.info riffraff.blogsome.com
work: cascaad.com circleme.com

+10.

Questa non una risposta, un articolo :slight_smile:

2012/3/2 gabriele renzi [email protected]

attr_reader :config

=> #<App:0x0000010086c440 @config=#<struct App::Config foo=“foo!”,
config.foo= ‘foo!’
end
Infatti se diventi esplicito funziona:

#method_missing e viene una cosa cos
end
MyApp = App.new

–
twitter: @riffraff
blog (en, it): www.riffraff.info riffraff.blogsome.com
work: cascaad.com circleme.com


Ml mailing list
[email protected]
http://lists.ruby-it.org/mailman/listinfo/ml

–
Andrea R.
Lelylan | reThink your house
http://lelylan.com

Grazie! Era proprio quello che volevo sapere.

Ho solo un dubbio:
MyApp.configure do
…

Sembra che ‘configure’ sia un metodo di classe… ma MyApp è un oggetto,
il cui nome convenzionalmente inizia con una lettera minuscola.

Ma sospetto che quanto ti hai descritto possa valere anche per
configurare attributi di classe. No?

Buon weekend

iwan

#configure in quel caso un metodo di classe, definito come
self.configure.
Cosa faccia poi non si sa, probabilmente imposta delle variabili di
istanza
sulla classe (che sono meglio delle @@) e poi probabilmente con un
block_given? se non gli passi un blocco ti ritorna la config.
E’ un’ottima maniera di rendere globale una configurazione senza
“sporcare”.

2012/3/2 Iwan B. [email protected]:

Grazie! Era proprio quello che volevo sapere.

Ho solo un dubbio:
MyApp.configure do
…

Sembra che ‘configure’ sia un metodo di classe… ma MyApp un oggetto,
il cui nome convenzionalmente inizia con una lettera minuscola.

gi ti ha risposto Luca su come fare per i metodi di classe, ma giusto
una precisazione: la convenzione non

classe → maiuscolo
istanza della classe → minuscolo

perch avrebbe poco senso, le classi sono oggetti come gli altri in ruby
:slight_smile:

La convenzione
costante → maiuscolo
variabile locale → minuscolo

Poi chiaramente le due cose vanno a sovrapporsi: in generale le classi
sono costanti quindi ruby ti impedisce come sintassi di scrivere

class
classe_con_nome_minuscolo_che_mi_farebbe_odiare_dalla_comunit_per_aver_infranto_le_convenzioni
end

E al contempo fa si che le classi siano disponibili quando fai require
di un file (mentre le variabili locali non lo sono)

Ma puoi fare tranquillamente

myclass = Class.new do

^o^

end

o

MySingleton = Something.new

–
twitter: @riffraff
blog (en, it): www.riffraff.info riffraff.blogsome.com
work: cascaad.com circleme.com