Los arrays declarados en meta.yaml se heredan por referencia

2 views
Skip to first unread message

Choan Gálvez

unread,
Apr 23, 2008, 10:43:25 AM4/23/08
to nano...@googlegroups.com
Hola majos.

Os cuento el problema que he encontrado y la ñapisolución que le he
dado. Si alguien tiene consejo, se lo agradeceré.

Amo allá.

Estaba haciéndome unos helpers para escupir etiquetas de script.
Digamos, tal que así (simplifico los métodos):

# añade la url de un script a la página
def add_script(url)
@page.scripts.add(url)
end

# salida HTML de la lista de scripts
def scripts
@page.scripts.each { |p| ... }
end

Cosas:

1. Para poder utilizar los métodos `scripts=` y `scripts` en cada
página, es necesario que cada página tenga definido, en su .yaml un
array (vacío o no) para la propiedad "scripts"

2. Para no tener que definir dicho array en cada página, Choan
presupuso que declarando `scripts: []` en meta.yaml tendría suficiente.

3. Craso error: la propiedad pasa a la página por referencia y no por
copia, así que si en una de las páginas hago algo tal que

<% add_script('/js/jquery.js') %>

la URL se añade a un único script.

Ñapisolución (para salir del paso): declarar el array vacío en las
propiedades de las páginas que van a usar el método add_script.

* * *

Reflexión: ¿no sería, digo yo, lo suyo, que las propiedades que se
heredan de meta.yaml se heredaran por copia?

¿Opiniones, consejos? ¿Algo que se le pueda proponer al belga?

Salud.
--
Choan Gálvez, que a veces escribe en su blog de toda la vida
<http://dizque.lacalabaza.net/>

Ale Muñoz

unread,
Apr 23, 2008, 2:27:09 PM4/23/08
to nano...@googlegroups.com
Choan,

sospecho que hay una solución más simple, pero es que no entiendo el
problema : )

¿Podrías explicar para qué estás usando ese tinglado, y poner algún ejemplo?


--
Ale Muñoz
http://sofanaranja.com
http://bomberstudios.com

Choan Gálvez

unread,
Apr 23, 2008, 3:17:39 PM4/23/08
to nano...@googlegroups.com
Hola.

On 23/04/2008, at 20:27, Ale Muñoz wrote:

> Choan,
>
> sospecho que hay una solución más simple, pero es que no entiendo el
> problema : )
>
> ¿Podrías explicar para qué estás usando ese tinglado, y poner algún
> ejemplo?

Me reexplico entonces, subiendo un poquito más arriba.

Estoy montando un sitio en el que algunas de las páginas incluyen
vídeos, algunas páginas llevan desplegables montados con js, etc.

Y mi santa intención es no cargar scripts a cascoporro para todas las
páginas. Así que he pensado "hagamos un par de funcioncicas que nos
hagan la cosa".

Por tanto, en mi biblioteca de funciones para el sitio, he definido
unos métodos para manejar la pila de scripts

* add_script(url) # añade un script a la pila de la página (si es que
no está)
* add_script_src(url) # añade fuente de script a la pila de la página
(código que se incluirá inline)
* scripts # devuelve la lista de scripts como HTML

Y estoy en proceso de añadir otros helpers como

def video(id, url, preview)
add_script('/js/swfobject.js')
add_script_src(%[ un pedazo de js generado "al vuelo" que se
incrustará en línea ])
%[<div id="#{id}"><img src="#{preview}" alt=""/></div>]
end

Entonces... el problema que decía haber detectado es el siguiente. Si
en "meta.yaml" tenemos

scripts: []

Y no redefinimos la propiedad `scripts` en los .yaml correspondientes
a las páginas, nanoc hace que la propiedad `scripts` de toda y cada
una de las páginas haga referencia al mismo array. De tal manera que
si en el contenido de la página "pag1" tenemos

add_script('/js/ohyeah.js')

el script no se añade a la pila de "pag1", se añade a una pila común
para todas las páginas. Y por tanto, al utilizar

<%= scripts %>

en el layout, el volcado que obtenemos es el correspondiente a todos
los scripts añadidos desde cualquier página.

Para salir del atasco, decía, he optado por definir la propiedad/
valor `scripts: []` para cada página. Probablemente, si me hubiera
atascado en otro momento del tiempo y el espacio, hubiera optado por
otra solución (como usar un hash utilizando como claves los paths de
las páginas o retirarme a vivir al campo). De hecho, ahora que lo
escribo, igual cambio de apaño.

¿Se me entiende mejor ahora? Si hace falta más ejemplo, haberlo haylo.

Salud para ellos, besitos para ellas.
--
Choan Gálvez, jugón
<http://detablero.com/>

Ale Muñoz

unread,
Apr 23, 2008, 4:29:32 PM4/23/08
to nano...@googlegroups.com
Vale, ahora lo pillo (es que uno es tardorreactivo por naturaleza : )

Pon esto en lib/default.rb

class Nanoc::PageProxy
def scripts
@scripts
end
def add_script src
if @scripts.nil?
@scripts = []
end
@scripts << src
end
end

def add_script src
@page.add_script src
end

def scripts
@page.scripts
end


y aluego en tu página:

<% add_script("foo") %>
<% add_script("bar") %>

<ul>
<% scripts.each do |s| %>
<li><%= s %>
<% end %>
</ul>

Creo que el código es sencillito y no tendrás problema en adaptarlo a
tu problema concreto ; )

Choan Gálvez

unread,
Apr 23, 2008, 5:03:18 PM4/23/08
to nano...@googlegroups.com
Hola.

On 23/04/2008, at 22:29, Ale Muñoz wrote:

> Vale, ahora lo pillo (es que uno es tardorreactivo por naturaleza : )
>
> Pon esto en lib/default.rb
>
> class Nanoc::PageProxy

Ahap, entonces, ¿podemos resumir tu respuesta en "extiende
Nanoc::PageProxy"?


> def scripts
> @scripts
> end
> def add_script src
> if @scripts.nil?
> @scripts = []
> end
> @scripts << src
> end
> end

Q: aún después de mirarme la documentación, no sé si hay o no
diferencia entre `Array.<<` y `Array.push`. ¿La hay?


> def add_script src
> @page.add_script src
> end
>
> def scripts
> @page.scripts
> end
>
>
> y aluego en tu página:
>
> <% add_script("foo") %>
> <% add_script("bar") %>
>
> <ul>
> <% scripts.each do |s| %>
> <li><%= s %>
> <% end %>
> </ul>
>
> Creo que el código es sencillito y no tendrás problema en adaptarlo a
> tu problema concreto ; )

Pues yo creo que sí, que me vendrá estupendamente.

Gracias.
--
Choan Gálvez, que cuando no trabaja duro escribe en
<http://cargaydescarga.com>

Sergio Gil Pérez de la Manga

unread,
Apr 23, 2008, 5:07:20 PM4/23/08
to nano...@googlegroups.com
Si me permite usted unas pequeñas rebajas =;-)

On Wed, Apr 23, 2008 at 10:29 PM, Ale Muñoz <bomber...@gmail.com> wrote:
> Vale, ahora lo pillo (es que uno es tardorreactivo por naturaleza : )
>
> Pon esto en lib/default.rb
>
> class Nanoc::PageProxy
> def scripts
> @scripts
> end
> def add_script src
> if @scripts.nil?
> @scripts = []
> end
> @scripts << src
> end
> end

class Nanoc::PageProxy
attr_accessor :scripts
def add_script(src)
self.scripts ||= []
self.scripts << src
end
end

Lo demás igual =;-)

--
Sergio Gil Pérez de la Manga
e-mail > sgil...@gmail.com
blog > http://www.lacoctelera.com/porras

Ale Muñoz

unread,
Apr 23, 2008, 6:14:58 PM4/23/08
to nano...@googlegroups.com
On Wed, Apr 23, 2008 at 11:07 PM, Sergio Gil Pérez de la Manga
<sgil...@gmail.com> wrote:
>
> Si me permite usted unas pequeñas rebajas =;-)
>

Viniendo de usted, como si quiere pegarle fuego a mi código y empezar
de cero : )

Lo del attr_accesor lo había probao, pero me daba un fallo bastante
bizarro, así que opté por la vieja técnica "don't worry, be crappy"
que tantas satisfacciones me ha dado en el pasado : )

Choan: que yo sepa (aunque Sergio me corregirá si me equivoco)
Array.<< y Array.push son sinónimos (Ruby, que es así de majete). El
pickaxe tampoco cuenta nada que haga pensar que son distintos.

Reply all
Reply to author
Forward
0 new messages