<rss version="2.0" 
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:content="http://purl.org/rss/1.0/modules/content/" 
>
<channel>
<title>cientifico.net</title>
<link>http://cientifico.net</link>
<description>&lt;small&gt;por&lt;/small&gt; Guillermo Álvarez</description>
<language>es-es</language>
<dc:subject>Tecnología</dc:subject>

<category domain="http://cientifico.net">blog</category>
<category domain="http://cientifico.net">de</category>
<category domain="http://cientifico.net">prueba</category>

<image>
	<url>http://d3ds4oy7g1wrqq.cloudfront.net/cientifico/f/01c58620d531acdef14fc3ba88fd2db4.jpg?Expires=1280527200&Signature=IbDfqaZPfWGNpvhYzOJD8NiZfwCqxoOWKjujMb~M-kxWUHo2NC9kZJoYPOwhTB3oUoE1EdLlUw9DssTa6LC~BbJxygs758V77E9oYklcHGDs5pO332ZmTUKYFfXQYJtYvmRLRXXvNRT47JpVm-nX3rqQY6SKDIihR3l2FhnFB5Y_&Key-Pair-Id=APKAJYN3LZI5CG46B7AA&Policy=eyJTdGF0ZW1lbnQiOlt7IlJlc291cmNlIjoiaHR0cDovL2QzZHM0b3k3ZzF3cnFxLmNsb3VkZnJvbnQubmV0L2NpZW50aWZpY28vZi8wMWM1ODYyMGQ1MzFhY2RlZjE0ZmMzYmE4OGZkMmRiNC5qcGciLCJDb25kaXRpb24iOnsiRGF0ZUxlc3NUaGFuIjp7IkFXUzpFcG9jaFRpbWUiOjEyODA1MjcyMDB9fX1dfQ__</url>
	<title>cientifico.net</title>
	<link>http://cientifico.net</link>
</image>
<generator>the-shaker v0.1. More on http://www.the-shaker.com</generator>
<item>
<title>nginx rails passenger mass deployment actually.</title>
<link>http://cientifico.net/post/2010/07/01/nginx-rails-passenger-mass-deployment-actually</link>
<pubDate>2010-07-01T16:37:32+00:00</pubDate>
<content:encoded><![CDATA[<div class="almost_half_cell">
<div dir="ltr"><span id="result_box" class="long_text"><span>I typically deploys several applications that do not have much load on one machine. I u</span><span>se the <a href="http://wiki.nginx.org/NginxVirtualHostExample">advanced nginx virtual host technic</a>(see Wildcard Subdomains in a Parent Folder).</p>
<p></span><span>I was rather surprised to see the article "</span><span><a href="http://blog.phusion.nl/2010/07/01/the-road-to-passenger-3-technology-preview-3-closing-the-gap-between-development-and-production-rethinking-the-word-easy/">new Passenger 3</a></span><span>", especially in the aspect of mass deployment. </span><span>Feature that since I have tested, works in nginx and Passenger series (do not know from which version).</p>
<p></span><span>The part of the nginx configuration that makes this possible is this:</span></span></div>
<pre name='code' class="ruby"> http {     # [...]     passenger_root /usr/local/lib/ruby/gems/1.8/gems/passenger-2.2.15;     passenger_ruby /usr/local/bin/ruby;              server {         listen 0.0.0.0:80;         root /var/www/servers/$host/public;         access_log /var/log/nginx/servers.access.log;         error_log /var/log/nginx/servers.error.log;          location / {            index index.html index.php;            passenger_enabled on;            autoindex  on;         }     }     # [...] }  </pre>
<div dir="ltr"><span id="result_box" class="long_text"><span></p>
<p></span><span>As soon as dir structure is as <a href="http://www.modrails.com/documentation/Users%20guide%20Nginx.html#deploying_a_rack_app">says on the documentation of Passenger</a> (config.ru  /tmp and /public) appears an application on the specific domain.</span></span></div>
<div><span id="result_box" class="long_text"><span><br /></span></span></div>
<div><span id="result_box" class="long_text"><span>So if you want to deploy a new app, just put the files on the server.</span></span></div>
<div><span id="result_box" class="long_text"><span><strong>ExtraBoll</strong>, for <strong>capistrano style</strong> deploys:</span></span></div>
<pre name='code' class="ruby"> http {        ...          server {         ...         root /var/www/servers/$host/current/public;     } } </pre>
</div>
]]></content:encoded>
<comments>
http://cientifico.net/post/2010/07/01/nginx-rails-passenger-mass-deployment-actually#comentarios
</comments>
</item>
<item>
<title>El curioso bucle begin end while. Balbuceando en alto.</title>
<link>http://cientifico.net/post/2009/04/21/el-curioso-bucle-begin-end-while-balbuceando-alto</link>
<pubDate>2009-04-21T00:00:41+00:00</pubDate>
<content:encoded><![CDATA[<p>Creo que todos conocemos una sintaxis parecida:
<div></div>
<div><font class="Apple-style-span" face="Courier">&nbsp;&nbsp;def function</font></div>
<div><font class="Apple-style-span" face="Courier">&nbsp;&nbsp; &nbsp;do something</font></div>
<div><font class="Apple-style-span" face="Courier">&nbsp;&nbsp; &nbsp;while condition&nbsp;</font></div>
<div><font class="Apple-style-span" face="Courier">&nbsp;&nbsp; &nbsp; &nbsp;do something</font></div>
<div><font class="Apple-style-span" face="Courier">&nbsp;&nbsp; &nbsp;end</font></div>
<div><font class="Apple-style-span" face="Courier">&nbsp;&nbsp;end</font></div>
<div></div>
<div>En la mayoría de lenguajes tenemos que ejecutar el primer ciclo del loop fuera del loop.</div>
<div>Pero en Ruby no.</div>
<div></div>
<div>
<div><font class="Apple-style-span" face="Courier">def temp_dir</font></div>
<div><font class="Apple-style-span" face="Courier">&nbsp;&nbsp;i = 0</font></div>
<div><font class="Apple-style-span" face="Courier">&nbsp;&nbsp;dir = File.join(Dir.tmpdir,'ginst', (i += 1).to_s)</font></div>
<div><font class="Apple-style-span" face="Courier">&nbsp;&nbsp;while(File.exists?(dir)) do</font></div>
<div>
<div><font class="Apple-style-span" face="Courier">&nbsp;&nbsp; &nbsp;dir = File.join(Dir.tmpdir,'ginst', (i += 1).to_s)</font></div>
<div><font class="Apple-style-span" face="Courier">&nbsp;&nbsp;end</font></div>
</div>
<div><font class="Apple-style-span" face="Courier">&nbsp;&nbsp;FileUtils.mkdir_p(dir)</font></div>
<div><font class="Apple-style-span" face="Courier">end</font></div>
<div></div>
<div>Casi sin querer, descubrí la siguiente sintaxis</div>
</div>
<div></div>
<div>Esto hace que se ejecute el código la primera vez y luego... &nbsp;si a la condición le apetece. Pero la primera, no te la quita nadie.</div>
<div></div>
<div>Esto me vino muy bien para hacer un generador de directorios temporales secuenciales:</div>
<div></div>
<div>
<div><font class="Apple-style-span" face="Courier">def temp_dir(i=0)</font></div>
<div><font class="Apple-style-span" face="Courier">&nbsp;&nbsp;begin</font></div>
<div><font class="Apple-style-span" face="Courier">&nbsp;&nbsp; &nbsp;dir = File.join(Dir.tmpdir,'ginst', (i += 1).to_s)</font></div>
<div><font class="Apple-style-span" face="Courier">&nbsp;&nbsp;end while(File.exists?(dir))</font></div>
<div><font class="Apple-style-span" face="Courier">&nbsp;&nbsp;FileUtils.mkdir_p(dir)</font></div>
<div><font class="Apple-style-span" face="Courier">end</font></div>
<div></div>
</div>
<div>Pero meditando un poco más, recordé una obviedad que tenía olvidada, y que la primera vez que la vi me sorprendió tanto como ahora, y es el poner el while a lo que quieras. Por ejemplo, si estás deprimido, qué mejor que estas cuatro palabras</div>
<div></div>
<div>puts 'Anímate' while true</div>
<div></div>
<div>Y si lo estás solo un poquito.</div>
<div></div>
<div>begin puts 'Venga tonto... ¡ Anímate ! ' end while false</div>
<div></div>
<div>Lo que me llevó a intentar hacer la función de los directorios en una linea</div>
<div></div>
<div>Primer intento:</div>
<div></div>
<div><font class="Apple-style-span" face="Courier">def temp_dir(i=0)</font></div>
<div><font class="Apple-style-span" face="Courier">&nbsp;&nbsp;begin &nbsp;dir = File.join(Dir.tmpdir,'ginst', (i += 1).to_s) end while (File.exists?(dir))</font></div>
<div>
<div><font class="Apple-style-span" face="Courier">&nbsp;&nbsp;FileUtils.mkdir_p(dir)</font></div>
<div><font class="Apple-style-span" face="Courier">end</font></div>
</div>
<div></div>
<div>El problema que tenemos con esta sintaxis es que lo último en ejecutarse del bloque es la condición, por lo que no podremos obtener el valor devuelto. Ahora bien, si podemos pasar un begin..end... &nbsp;¿Quién nos prohibe pasar la sintaxis de toda la vida begin..begin..end..while..end .</div>
<div></div>
<div><font class="Apple-style-span" face="Courier">def temp_dir(i=0)</font></div>
<div>
<div><font class="Apple-style-span" face="Courier">&nbsp;&nbsp;FileUtils.mkdir_p(begin begin dir = File.join(Dir.tmpdir,'ginst', (i += 1).to_s) end while File.exists?(dir) ; dir end)</font></div>
<div><font class="Apple-style-span" face="Courier">end</font></div>
</div>
<div></div>
<div>
<div>De aquí, llama la atención el poder estar usando bloques dentro de argumentos con la misma facilidad que a mi se me convence para ir de fiesta.</div>
<div></div>
</div>
<div>Vale, hice una trampa. Inicializar la variable como parámetro. Pero tiene solución:</div>
<div></div>
<div>
<div><font class="Apple-style-span" face="Courier">def temp_dir</font></div>
<div>
<div><font class="Apple-style-span" face="Courier">&nbsp;&nbsp;FileUtils.mkdir_p(begin begin dir = File.join(Dir.tmpdir,'ginst', (i ||=0 ; i+= 1).to_s) end while File.exists?(dir) ; dir end)</font></div>
<div><font class="Apple-style-span" face="Courier">end</font></div>
</div>
</div>
<div></div>
<div>Pese a no ser práctico sobre ninguno de los casos expuestos, ya que ofuscar nuestro código, aunque mola, no es útil, me ha vuelto a llamar la atención, la versatilidad que puede haber en ruby.</div>
<div></div>
<div>Y como inquieto que soy... no puedo parar de preguntarme ¿y si...? Y sí funciona en ruby1.9, pero con la salvedad de que FileUtils.mkdir_p devuelve un array (creo que también los conocen como arreglos de algo) en vez de una cadena o string.</div>
<div></div>
<div></div>
<div>Y a tí... ¿ Hay alguna sintaxis de ruby que te llame especialmente la atención ?</div>
<div></div>
<div></div>
<div></div>
</p>]]></content:encoded>
<comments>
http://cientifico.net/post/2009/04/21/el-curioso-bucle-begin-end-while-balbuceando-alto#comentarios
</comments>
</item>
<item>
<title>Crear y eliminar tags remotos con git</title>
<link>http://cientifico.net/post/2009/04/19/crear-y-eliminar-tags-remotos-con-git</link>
<pubDate>2009-04-19T17:25:00+00:00</pubDate>
<content:encoded><![CDATA[<p>Manejar tags localmente es fácil:</p>
<p>> git tag -l  # lista los tags locales<br />
> git tag tag_name # Crea un tag local<br />
> git tag -d tag_name # Borra el tag local<br />
><br />
> git tag -d `git tag -l `  # Borra todos los tags locales</p>
<p>Pero manejar los remotos... no es tan intuitivo, así que me dejo esta<br />
pequeña nota:</p>
<p>> git fetch --tags  #Aunque ya lo hace por defecto<br />
> git ls-remote --tags origin # Lista los tags remotos</p>
<p>Y para borrarlo, tendremos que borrar primero el local y luego hacer:</p>
<p>> git push origin :refs/tags/tag_name</p>
<p>---Adjuntos---<br /><br />
<a href="http://www.lacoctelera.com/myfiles/cientifico/smime-3.p7s?Expires=1280527200&Signature=LEvRuzFPQ7WjRtX2GVoP6VWXpXI6WRlaAFMBSmFow6WtiVhIvdKFgKqR5jT~qrpwqyrcc-6UC-kv-w2UEHva0q-W3T35Zyi9hdjvGKWQNbGRdP3l7FE4ckzSeQhvjY9xJGTWeAD79m2pe6ykoHf8ivQCskEEOh95ojvhMVVT5mY_&Key-Pair-Id=APKAJYN3LZI5CG46B7AA&Policy=eyJTdGF0ZW1lbnQiOlt7IlJlc291cmNlIjoiaHR0cDovL2QzZHM0b3k3ZzF3cnFxLmNsb3VkZnJvbnQubmV0L2NpZW50aWZpY28vbXlmaWxlcy9zbWltZS0zLnA3cyIsIkNvbmRpdGlvbiI6eyJEYXRlTGVzc1RoYW4iOnsiQVdTOkVwb2NoVGltZSI6MTI4MDUyNzIwMH19fV19">smime-3.p7s</a><br />
</p>
]]></content:encoded>
<comments>
http://cientifico.net/post/2009/04/19/crear-y-eliminar-tags-remotos-con-git#comentarios
</comments>
</item>
<item>
<title>Variables especiales de ruby</title>
<link>http://cientifico.net/post/2009/02/04/variables-especiales-ruby</link>
<pubDate>2009-02-04T11:45:43+00:00</pubDate>
<content:encoded><![CDATA[<div>A modo de chuletario personal, dejo esta imagen con las variables especiales de ruby.</div>
<div></div>
<div>Siempre conocida y sabida, hasta que requieres algunos de sus valores, es entonces cuando echas de menos este chuletario.</div>
<div></div>
<div></div>
<p><img class="imgcen" src="http://cientifico.net/myfiles/cientifico/Imagen-1-2.png" alt="" /></p>
]]></content:encoded>
<comments>
http://cientifico.net/post/2009/02/04/variables-especiales-ruby#comentarios
</comments>
</item>
<item>
<title>Increible video.</title>
<link>http://cientifico.net/post/2009/01/31/increible-video</link>
<pubDate>2009-01-31T16:38:16+00:00</pubDate>
<content:encoded><![CDATA[<p> <img class="imgCen" src="http://cientifico.net/myfiles/cientifico/how-to-confuse-an-idiot-exclusive-youtube-video.jpg.jpeg" alt="" width="400" height="319" /></p>
]]></content:encoded>
<comments>
http://cientifico.net/post/2009/01/31/increible-video#comentarios
</comments>
</item>
<item>
<title>Cucumber: Testeando ajax sin selenium (II)</title>
<link>http://cientifico.net/post/2009/01/23/cucumber-testeando-ajax-sin-selenium-ii</link>
<pubDate>2009-01-23T14:05:09+00:00</pubDate>
<content:encoded><![CDATA[<p><img style='border:0px' class="imgizqda" src="http://cientifico.net/myfiles/cientifico/freakyinsertions5.jpg_thumbnail.png" alt="" />Continuando con el artículo <a href="http://cientifico.net/post/2009/01/23/cucumber-testeando-ajax-sin-selenium">Testeando ajax sin selenium</a> han mejorado algunas cosillas.</p>
<p>La versión anterio, tenía un problema y es que solo servía para visitar. ¿Pero que pasa con el resto de steps (como I press), que implican peticiones y que esperan ajax como respuesta? Pues aquí está la solución.</p>
<pre name='code' class="ruby">When /^(.*) as an ajax request/ do |task|   When task   response.body = get_ajax_html(response.body) end </pre>
<p>Esto dota a las features de poder realizar cualquier acción que antes hacías y evaluar su respuesta. Por lo tanto, lo que antes era:</p>
<pre name='code'  class="ruby">    And I press "Guardar" </pre>
<p>Ahora es</p>
<pre name='code'  class="ruby" style="border:red 5px">    And I press "Guardar" as an ajax request </pre>
<p>Como extensión, he visto que otras formas de page.update, usan la función javascript html en vez de replace with, por  lo que la función que obtiene el cuerpo ha sido actualizada.</p>
<pre  name='code'  class="ruby">def get_replace_with_body(body)   body=~/replaceWith\(\"(.*?)[^\\]\"\)/m   body=~/\)\.html\(\"(.*?)[^\\]\"\)/m unless $1   raise Exception.new('The ajax response doesn\'t containg a js replaceWith method') unless $1   "#{$1}" end </pre>
<p>Y ahora <strong>ya puedo testear casi todo el js </strong>sin usar selinium, configurar una máquina virtual, un xen, linux, firefox, selenium_server, etc...</p>
]]></content:encoded>
<comments>
http://cientifico.net/post/2009/01/23/cucumber-testeando-ajax-sin-selenium-ii#comentarios
</comments>
</item>
<item>
<title>Cucumber testeando ajax sin selenium</title>
<link>http://cientifico.net/post/2009/01/23/cucumber-testeando-ajax-sin-selenium</link>
<pubDate>2009-01-23T00:59:02+00:00</pubDate>
<content:encoded><![CDATA[<p><img class="imgdcha" src="http://cientifico.net/myfiles/cientifico/311155tyCX_w.jpg_thumbnail-1.png" alt="">Como quería terminar una cosa, y lo que necesita más que test de vista o test de controlador era un test de integración, no me quedó otra que dotar a cucumber+webrat-selenium  (nuestro entorno de feature testín) de capacidad de ajax.</p>
<p>Bueno, seamos serios, son un par de lineas que me permitieron hacer ejecutar la feature, y paso a comentar, ya que de tratarse de aplicaciones rails, este método es usable para la mayoría de page.update que realizamos.</p>
<p>page.update actualiza un elemento del dom con nuevo contenido, para eso lanza un javascript que es interpretado por el navegador. Suponiendo que usamos jquery (tal vez cambie la implementación para el antiguo y obsoleto prototype), este hará un replaceWith. <strong>Este código parsea el código devuelto por la aplicación y extrae la actualización de la página.</strong></p>
<p>Pasemos ahora a ver el código:</p>
<pre name='code' class="ruby"># Desescapamos javascript, ya que escapado no nos sirve de mucho. # Así tendremos un html válido. Esto se resume en: #  < div id="\'hola\'">\tadios\t< /div>  ===>    adios   def unescape_javascript(javascript)  javascript.gsub!('\n' , "\n")  javascript.gsub!('\t' , "\t")  javascript.gsub!("\\'", "'")  javascript.gsub!('\"' , '"') end  # Expresión regular encargada de sacar lo que realmente nos intersa. #  ...replaceWith(' ESTO NOS INTERESA ')... def get_replace_with_body(body)  body=~/replaceWith\(\"(.*?)[^\\]\"\)/m  raise Exception.new('The ajax response doesn\'t containg a js replaceWith method') unless $1  "#{$1}" end  # Combinado de las dos anteriores def get_ajax_html(text)  unescape_javascript(get_replace_with_body(text)) end </pre>
<p>Y el step correspondiente.</p>
<pre name='code'  class="ruby">When /^I visits by ajax (.*) $/ do |path|  visits(path)  response.body = get_ajax_html(response.body) end </pre>
<p>Y la feature</p>
<pre name='code' class="ruby"> Scenario: Changing my name    Given I am a logged in as a Candidate    When I visits /profile/edit.js ajax    And I fill in "candidate_profile_first_name" with "Guillermooo"    And I fill in "candidate_profile_surnames" with "Alvarez"    And I press "Guardar"    Then I should see "Guillermooo Alvarez" </pre>
<p>La solución es fea, torpe, poco optima. Pero creo que puede resolver la mayoría de peticiones ajax del servidor sin depender de un motor javascript externo.<br />
Si alguien conoce alguna otra forma sin incorporar más dependencias al testing... que me lo haga saber.
</p>
]]></content:encoded>
<comments>
http://cientifico.net/post/2009/01/23/cucumber-testeando-ajax-sin-selenium#comentarios
</comments>
</item>
<item>
<title>Truquitos servidor</title>
<link>http://cientifico.net/post/2009/01/05/truquitos-servidor</link>
<pubDate>2009-01-05T17:34:53+00:00</pubDate>
<content:encoded><![CDATA[<p><img class="imgdcha" src="http://cientifico.net/myfiles/cientifico/310.jpg.jpeg" alt="" />Basándonos en la teoría de que las máquinas están bien configuradas en lo que respecta el correo, yo voy a tener cientifico.net para correos personales y yolanda.cientifico.net para los correos locales de la máquina.</p>
<p>Esto permite que yo desde cualquier cuenta de correo envie un mensaje a guillermo @ yolanda cientifico PUNTO net.</p>
<p>Para que sirve esto.... pues para ser más comodón aún. Soy fiel usuario de scp (consola -&gt; servidor) y webdav (escritorio&lt;-&gt;servidor), pero poder enviar archivos a mi cuenta del servidor y al llegar allí, arrancar alpine o cualquier otro cliente de correo de consola, y poder guardarlo, es una gozada.</p>
<p>Ahí queda dicho.</p>
]]></content:encoded>
<comments>
http://cientifico.net/post/2009/01/05/truquitos-servidor#comentarios
</comments>
</item>
<item>
<title>DRB</title>
<link>http://cientifico.net/post/2009/01/04/drb</link>
<pubDate>2009-01-04T02:44:04+00:00</pubDate>
<content:encoded><![CDATA[<p><img class="imgdcha" src="http://cientifico.net/myfiles/cientifico/Imagen-4.png" alt="">DRB o <a href="http://www.ruby-doc.org/stdlib/libdoc/drb/rdoc/index.html">Distributed Ruby</a> es una abstracción de sockets tcp y serialización de objetos que trae integrada ruby por defecto.</p>
<p>Tenía ganas de jugar con drb y su abstracción superior sobre el patron <a href="http://en.wikipedia.org/wiki/JavaSpaces">tuple spaces</a> que es una forma de implementar el paradigma de memoria asociativa (<a title="Content-addressable memory" href="http://en.wikipedia.org/wiki/Content-addressable_memory">associative memory</a>) desda <a href="http://en.wikipedia.org/wiki/Linda_(coordination_language)">linda</a>, que es una forma de coordinar y comunicar diferentes procesos entre máquinas. Ya jugaremos con <a href="http://www.ruby-doc.org/stdlib/libdoc/rinda/rdoc/index.html">Rinda</a>, pero como bien dice mi amigo Jack... Vayamos por partes.</p>
<p>En este caso vamos a poner un caso real en rails para procesar emails. No es que sea necesario utilizar DRb, es que es la única forma rentable que he encontrado. Recibimos e-mails con una frecuencia indeterminada, y los procesamos desde una tarea rake. Esto está bien salvo por que levantar una tarea rake que como dependencia tiene :environment, puede suponer bastante tiempo. Si supone 10 segundos y cada instancia supone 40 o 50 megas. 10 correos por segundo... tumbarían la máquina.</p>
<p>Pues lejos de ir más lejos se implementa una arquitectura cliente-servidor en el que el servidor es la tarea rake y el cliente es lo que se conecta con el <a href="http://www.google.es/url?sa=t&amp;ct=res&amp;cd=2&amp;url=http%3A%2F%2Fes.wikipedia.org%2Fwiki%2FAgente_de_Transporte_de_Correo&amp;ei=yfmpSKG9MYnA0wTzkJG3Dw&amp;usg=AFQjCNHJIyPyXY0JSfjxH_I1xNjcqQFjcw&amp;sig2=9HyJs0P7hKH3PQXmRm1yCA">MTA</a>(Mail Transfer Agent) del sistema. Al grano:</p>
<p>El cliente, solo necesita esto</p>
<pre name='code' class="ruby">#!/usr/bin/env ruby  require 'drb'  URI="druby://localhost:9999"   server = DRbObject.new_with_uri URI  return server.process($stdin.read.to_s)  </pre>
<p>Mientras que el servidor se arreglaría con esto</p>
<pre name='code' class="ruby">    desc 'Start Mail Daemon'    task :daemon =&gt; :environment do      require 'drb'      URI="druby://localhost:9999"      class Processor        def process(mail)          ModeloActiveRecordParaMails.create(TMail.new(mail))        end      end       DRb.start_service URI, Processor.new      DRb.thread.join    end </pre>
<p>Con esto estaría ya  todo el trabajo hecho.</p>
<p>Creo que el código es bastante auto-explicativo. Si hay alguna duda... A los comentarios.
</p>
]]></content:encoded>
<comments>
http://cientifico.net/post/2009/01/04/drb#comentarios
</comments>
</item>
<item>
<title>Diferencia entre extend e include (extend vs include)</title>
<link>http://cientifico.net/post/2008/12/30/diferencia-entre-extend-e-include-extend-vs-include</link>
<pubDate>2008-12-30T12:45:36+00:00</pubDate>
<content:encoded><![CDATA[<p>La diferencia entre <em>extend</em> e <em>include</em> puede ser confusa a veces, por eso voy a intentar aclarar, como creo yo que es. Pero primero echemos un vistazo al rdoc</p>
<h3>Obj.extend Mod.include</h3>
<p><img src="http://cientifico.net/myfiles/cientifico/Imagen-3.png" alt="" class="imgcen" /><br />
<img src="http://cientifico.net/myfiles/cientifico/Imagen-2.png" alt="" class="imgcen" /><br />
<img src="http://cientifico.net/myfiles/cientifico/Imagen-1.png" alt="" class="imgcen" /></p>
<h3>A jugar...</h3>
<p> Vamos a poner este código de ejemplo:</p>
<pre name="code" class="ruby"> module A   def a     puts "Has llamado a A#a"   end end  module B   def b     puts "Has llamado a B#b"   end end  class C   include A   extend B end </pre>
<p>La diferencia es que <strong>los métodos del módulo A son para la instancia y los métodos del módulo B son para la clase</strong> por lo que sería lo mismo que hacer:</p>
<pre name="code" class="ruby"> class D   include A   class << self     include B   end end </pre>
<p>Esta técnica es muy usada en frameworks como merb. Cuando un objeto es incluido, se llama a:</p>
<pre name="code" class="ruby">   include InstanceMethods   extend ClassMethods </pre>
<p>Este es uno de los usos más típicos que he visto de include vs extend</p>
<p>Otras diferencias que me vienen a la mente son:</P>
<ol>
<li><em>extend</em> es un método público, mientras que <em>include</em> no.</li>
<li>
<p>Si se llama a una a <em>extend</em> de una instancia, es lo mismo que si la abrieses e incluyeses el módulo.</p>
</li>
<pre name="code" class="ruby"> o = Object.new o.extend A class << o   include B end  o.a #=> Has llamado a A#a o.b #=> Has llamado a B#b </pre>
</ol>
<p>Y hasta donde yo se... no tiene mucho más misterio</p>
</p></<>]]></content:encoded>
<comments>
http://cientifico.net/post/2008/12/30/diferencia-entre-extend-e-include-extend-vs-include#comentarios
</comments>
</item>
 
</channel>
</rss>
