<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>def Tenako.blog () end &#187; ruby</title>
	<atom:link href="http://blog.tenako.com/category/programacion/ruby/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.tenako.com</link>
	<description></description>
	<lastBuildDate>Mon, 19 Jul 2010 17:32:02 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Ruby: gmaps-geocode 0.1.0 is out !!</title>
		<link>http://blog.tenako.com/2009/07/04/ruby-gmaps-geocode-0-1-0-is-out/</link>
		<comments>http://blog.tenako.com/2009/07/04/ruby-gmaps-geocode-0-1-0-is-out/#comments</comments>
		<pubDate>Sat, 04 Jul 2009 20:12:24 +0000</pubDate>
		<dc:creator>farruco</dc:creator>
				<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://blog.tenako.com/2009/07/04/ruby-gmaps-geocode-0-1-0-is-out/</guid>
		<description><![CDATA[Disponible en github
]]></description>
			<content:encoded><![CDATA[<p>Disponible en <a title="gmaps-geocode at github" href="http://github.com/madtrick/gmaps-geocode/tree/master" onclick="javascript:pageTracker._trackPageview('/outbound/article/github.com');" target="_blank">github</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.tenako.com/2009/07/04/ruby-gmaps-geocode-0-1-0-is-out/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ruby: ¡Cállate IRB!</title>
		<link>http://blog.tenako.com/2009/06/22/ruby-%c2%a1callate-irb/</link>
		<comments>http://blog.tenako.com/2009/06/22/ruby-%c2%a1callate-irb/#comments</comments>
		<pubDate>Mon, 22 Jun 2009 09:45:46 +0000</pubDate>
		<dc:creator>farruco</dc:creator>
				<category><![CDATA[programacion]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://blog.tenako.com/?p=194</guid>
		<description><![CDATA[¿Harto de que en alguna ocasión IRB sea demasiado verboso? Yo si.
Por defecto, IRB siempre &#8220;escupirá&#8221; el valor resultante de evaluar la expresión introducida por el usuario. Aunque la mayoría de las veces eso está bien, hay otras en las que sacarias el corazón con una cucharilla de Té  a quien tuvieras delante por la [...]]]></description>
			<content:encoded><![CDATA[<p>¿Harto de que en alguna ocasión IRB sea demasiado verboso? Yo si.</p>
<p>Por defecto, IRB siempre &#8220;escupirá&#8221; el valor resultante de evaluar la expresión introducida por el usuario. Aunque la mayoría de las veces eso está bien, hay otras en las que sacarias el corazón con una cucharilla de Té  a quien tuvieras delante por la crispación que produce esta &#8220;verbosidad&#8221;.</p>
<p>Me refiero a situaciones del tipo &#8220;quiero recorrer un array y listar el nombre de sus elementos con puts&#8221;, ejemplo:</p>
<pre class="brush: ruby;">
ArrayEnorme.each do |element| puts &quot;#{element.name}\n&quot; end
</pre>
<p>Con el código anterior vamos a mostrar el nombre de cada elemento del Array. Hasta aquí todo normal. El problema de evaluar esto en IRB es que, si ArrayEnorme tiene bastantes elementos y cada elemento tiene bastantes atributos, las lineas que imprimos con el nombre de cada elemento quedaran &#8220;sepultadas&#8221; por un mont<span>ón</span> de datos inutiles. Es decir, si el buffer de nuestra consola no se ha llenado con estos datos inutiles (perdiendo así las lineas con el nombre de cada elemento) tendremos que hacer scroll <em>ad-infinitum</em>, que para el caso es casí como si se hubierán perdido.</p>
<p>Para evitar esto, os presento mi solución de andar por casa:</p>
<pre class="brush: ruby;">

def toggle_output
context.return_format == &quot;Output canceled\n&quot; ? IRB.conf[:PROMPT][context.prompt_mode][:RETURN] : context.return_format = &quot;Output canceled\n&quot;
end

alias tgo toggle_output
</pre>
<p>Después de copiar las lineas anteriores en nuestro .irbrc podemos hacer pruebas:</p>
<pre class="brush: bash;">
madtrick::madtrick::$irb
irb(main):001:0&gt; 2 + 1
=&gt; 3
irb(main):002:0&gt; toggle_output
Output canceled
irb(main):003:0&gt; 2 + 1
Output canceled
irb(main):004:0&gt; toggle_output
=&gt; &quot;=&gt; %s\n&quot;
irb(main):005:0&gt; 2 + 1
=&gt; 3
</pre>
<p>Y <em>voila</em>, ya podemos callar y dar voz a IRB cuando nos plazca.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.tenako.com/2009/06/22/ruby-%c2%a1callate-irb/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ruby: Sketches en IRB</title>
		<link>http://blog.tenako.com/2009/06/19/ruby-sketches-en-irb/</link>
		<comments>http://blog.tenako.com/2009/06/19/ruby-sketches-en-irb/#comments</comments>
		<pubDate>Fri, 19 Jun 2009 16:47:14 +0000</pubDate>
		<dc:creator>farruco</dc:creator>
				<category><![CDATA[programacion]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[irb]]></category>
		<category><![CDATA[sketches]]></category>

		<guid isPermaLink="false">http://blog.tenako.com/?p=188</guid>
		<description><![CDATA[Hoy descubrí una gema m-a-r-a-v-i-l-l-o-s-a: Sketches.
El concepto que implementa sketches es sencillo: las modificicaciones que hagamos en nuestro editor de texto, se reflejan al instante en la sesión de irb. Es decir, si en el editor de texto creamos una clase y guardamos los cambios, la clase estará disponible automaticamente en la sesión de irb.
Su [...]]]></description>
			<content:encoded><![CDATA[<p>Hoy descubrí una gema m-a-r-a-v-i-l-l-o-s-a: <a href="http://sketches.rubyforge.org/" onclick="javascript:pageTracker._trackPageview('/outbound/article/sketches.rubyforge.org');" target="_blank">Sketches</a>.</p>
<p>El concepto que implementa sketches es sencillo: las modificicaciones que hagamos en nuestro editor de texto, se reflejan al instante en la sesión de irb. Es decir, si en el editor de texto creamos una clase y guardamos los cambios, la clase estará disponible automaticamente en la sesión de irb.</p>
<p>Su utilización es sencilla: arrancamos el IRB y lanzamos nuestro editor favorito con el comando sketch. A partir de ahí, el funcionamiento es como expliqué antes.</p>
<p>Mola : )</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.tenako.com/2009/06/19/ruby-sketches-en-irb/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ruby: callcc</title>
		<link>http://blog.tenako.com/2009/06/03/ruby-callc/</link>
		<comments>http://blog.tenako.com/2009/06/03/ruby-callc/#comments</comments>
		<pubDate>Wed, 03 Jun 2009 15:04:00 +0000</pubDate>
		<dc:creator>farruco</dc:creator>
				<category><![CDATA[programacion]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[callcc]]></category>
		<category><![CDATA[continuations]]></category>
		<category><![CDATA[frame]]></category>
		<category><![CDATA[stack]]></category>

		<guid isPermaLink="false">http://blog.tenako.com/?p=160</guid>
		<description><![CDATA[callcc, es la abreviatura de call-with-current-continuation, algo así como un goto con esteroides.
En el rdoc nos encontramos con la siguiente definición:


callcc &#123;&#124;cont&#124; block &#125; =&#62; obj

Generates a Continuation object, which it passes to the associated block. Performing a cont.call will cause the callcc to return (as will falling through the end of the block). The [...]]]></description>
			<content:encoded><![CDATA[<p><strong>callcc</strong>, es la abreviatura de call-with-current-continuation, algo así como un goto con esteroides.</p>
<p>En el <a href="http://www.ruby-doc.org/core/classes/Kernel.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.ruby-doc.org');" target="_blank">rdoc</a> nos encontramos con la siguiente definición:</p>
<blockquote>

<div class="wp_syntax"><div class="code"><pre class="ruby ruby" style="font-family:monospace;">callcc <span style="color:#006600; font-weight:bold;">&#123;</span>|cont| block <span style="color:#006600; font-weight:bold;">&#125;</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> obj</pre></div></div>

<p>Generates a Continuation object, which it passes to the associated block. Performing a cont.call will cause the callcc to return (as will falling through the end of the block). The value returned by the callcc is the value of the block, or the value passed to cont.call. See class Continuation for more details. Also see Kernel::throw for an alternative mechanism for unwinding a call stack.
</p></blockquote>
<p>Un tanto críptico, ¿No?. Basicamente, callcc almacena la dirección de memoria y el contexto  (en un objeto <a href="http://www.ruby-doc.org/docs/ProgrammingRuby/html/ref_c_continuation.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.ruby-doc.org');" target="_blank">Continuation</a>) de donde se le llamo. Sigue siendo raro,¿No?</p>
<p>Mejor un ejemplo. Sea el siguiente metodo:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby ruby" style="font-family:monospace;">&nbsp;
counter = 0
&nbsp;
<span style="color:#9966CC; font-weight:bold;">def</span> foo
<span style="color:#CC0066; font-weight:bold;">exit</span> <span style="color:#9966CC; font-weight:bold;">if</span> callcc<span style="color:#006600; font-weight:bold;">&#123;</span>|$cont| <span style="color:#006600; font-weight:bold;">&#125;</span> == <span style="color:#006666;">3</span>
<span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;hello world&quot;</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
foo
&nbsp;
<span style="color:#ff6633; font-weight:bold;">$cont</span>.<span style="color:#9900CC;">call</span><span style="color:#006600; font-weight:bold;">&#40;</span>counter <span style="color:#006600; font-weight:bold;">+</span>= <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#41;</span></pre></div></div>

<p>(Si ya se que las variables globales son malignas : ( )</p>
<p>Ejecutando el ejemplo:</p>

<div class="wp_syntax"><div class="code"><pre class="bash bash" style="font-family:monospace;">madtrick::madtrick::<span style="color: #007800;">$ruby</span> test3.rb
hello world
hello world
hello world</pre></div></div>

<p>Como se puede apreciar, se imprimen tres &#8220;hello world&#8221; con sólo una llamada al método foo. </p>
<p>¿Qué podemos extraer del ejemplo anterior?</p>
<ul>
<li> Cada llamada a la continuación ($cont) nos vuelve a llevar a linea donde se definió.</li>
<li> Si en la llamada a la continuación pasamos algun parámetro, este es devuelto por callcc</li>
</ul>
<p>Tambien podríamos utilizar los ejemplos del post anterior (<a href="http://blog.tenako.com/2009/06/01/ruby-tco-tail-call-optimization/"  target="_blank">Tail Call Optimization</a>) para explicar el funcionamiento de callcc:</p>
<p>Calculo del factorial de un número:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> TCOTest
  <span style="color:#008000; font-style:italic;"># tail-recursive factorial</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> fact<span style="color:#006600; font-weight:bold;">&#40;</span> n, acc = <span style="color:#006666;">1</span> <span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">if</span> n <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#006666;">2</span> <span style="color:#9966CC; font-weight:bold;">then</span>
      acc
    <span style="color:#9966CC; font-weight:bold;">else</span>
       fact<span style="color:#006600; font-weight:bold;">&#40;</span> n<span style="color:#006600; font-weight:bold;">-</span><span style="color:#006666;">1</span>, n<span style="color:#006600; font-weight:bold;">*</span>acc <span style="color:#006600; font-weight:bold;">&#41;</span> 
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> fact_cc<span style="color:#006600; font-weight:bold;">&#40;</span> n, acc = <span style="color:#006666;">1</span> <span style="color:#006600; font-weight:bold;">&#41;</span>
    cont = callcc<span style="color:#006600; font-weight:bold;">&#123;</span>|cont| cont<span style="color:#006600; font-weight:bold;">&#125;</span>
    <span style="color:#9966CC; font-weight:bold;">if</span> n <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#006666;">2</span> <span style="color:#9966CC; font-weight:bold;">then</span>
      acc
    <span style="color:#9966CC; font-weight:bold;">else</span>
       n, acc = n<span style="color:#006600; font-weight:bold;">-</span><span style="color:#006666;">1</span>, n<span style="color:#006600; font-weight:bold;">*</span>acc
       cont.<span style="color:#9900CC;">call</span> cont 
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#008000; font-style:italic;"># length of factorial</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> fact_size<span style="color:#006600; font-weight:bold;">&#40;</span> n <span style="color:#006600; font-weight:bold;">&#41;</span>
    fact<span style="color:#006600; font-weight:bold;">&#40;</span> n <span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">size</span>
  <span style="color:#9966CC; font-weight:bold;">rescue</span>
    $!
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
&nbsp;
  <span style="color:#008000; font-style:italic;"># length of factorial</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> fact_size_cc<span style="color:#006600; font-weight:bold;">&#40;</span> n <span style="color:#006600; font-weight:bold;">&#41;</span>
    fact_cc<span style="color:#006600; font-weight:bold;">&#40;</span> n <span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">size</span>
  <span style="color:#9966CC; font-weight:bold;">rescue</span>
    $!
  <span style="color:#9966CC; font-weight:bold;">end</span>  
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Si lo probamos en el irb vemos que fact_size_cc no da ningún tipo de problema mientras que la función fact_size (sí, por carecer Ruby de TCO) ya que nos quedamos sin espacio en la stack.</p>

<div class="wp_syntax"><div class="code"><pre class="bash bash" style="font-family:monospace;">...
irb<span style="color: #7a0874; font-weight: bold;">&#40;</span>main<span style="color: #7a0874; font-weight: bold;">&#41;</span>:009:0<span style="color: #000000; font-weight: bold;">&gt;</span> t.fact_size <span style="color: #000000;">10000</span>
=<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #666666; font-style: italic;">#&lt;SystemStackError: stack level too deep&gt;</span>
irb<span style="color: #7a0874; font-weight: bold;">&#40;</span>main<span style="color: #7a0874; font-weight: bold;">&#41;</span>:010:0<span style="color: #000000; font-weight: bold;">&gt;</span> t.fact_size_cc <span style="color: #000000;">10000</span>
=<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #000000;">14808</span></pre></div></div>

<p>El otro ejemplo del post anterior, la función de Fibonacci:</p>
<p>En el ejemplo anterior, utilizábamos la palabra reservada <strong>redo</strong> junto con  un método definido ad-hoc para poder realizar el cálculo:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby ruby" style="font-family:monospace;">  define_method<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:acc</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span> |i, n, result|
    <span style="color:#9966CC; font-weight:bold;">if</span> i == <span style="color:#006600; font-weight:bold;">-</span><span style="color:#006666;">1</span>
      result
    <span style="color:#9966CC; font-weight:bold;">else</span>
      i, n, result = i <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#006666;">1</span>, n <span style="color:#006600; font-weight:bold;">+</span> result, n
      <span style="color:#9966CC; font-weight:bold;">redo</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">def</span> fib_redo<span style="color:#006600; font-weight:bold;">&#40;</span>i<span style="color:#006600; font-weight:bold;">&#41;</span>
   acc i,<span style="color:#006666;">1</span>,0
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Pero tambien se podria haber hecho de esta otra forma:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">def</span> fib_call_cc<span style="color:#006600; font-weight:bold;">&#40;</span>i, n = <span style="color:#006666;">1</span>, result = 0<span style="color:#006600; font-weight:bold;">&#41;</span>
  cont = callcc<span style="color:#006600; font-weight:bold;">&#123;</span>|cont| cont<span style="color:#006600; font-weight:bold;">&#125;</span>
  <span style="color:#9966CC; font-weight:bold;">if</span> i == <span style="color:#006600; font-weight:bold;">-</span><span style="color:#006666;">1</span>
    result
  <span style="color:#9966CC; font-weight:bold;">else</span>
    i, n, result = i <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#006666;">1</span>, n <span style="color:#006600; font-weight:bold;">+</span> result, n
    cont.<span style="color:#9900CC;">call</span> cont
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>En el ejemplo anterior se puede apreciar como el contexto se mantiene. En este caso para los valores <strong>i</strong>,<strong>n</strong> y <strong>result</strong>.</p>
<p>Si ejecutamos un simple benchmark (para n en 50000) para comparar redo vs callcc, obtenemos los siguiente:</p>

<div class="wp_syntax"><div class="code"><pre class="bash bash" style="font-family:monospace;">&nbsp;
madtrick::madtrick::<span style="color: #007800;">$ruby</span> test.rb 
Time <span style="color: #000000; font-weight: bold;">for</span> fib_redo:      <span style="color: #000000;">0.390000</span>   <span style="color: #000000;">0.010000</span>   <span style="color: #000000;">0.400000</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span>  <span style="color: #000000;">0.403986</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
Time <span style="color: #000000; font-weight: bold;">for</span> fib_call_cc:   <span style="color: #000000;">0.500000</span>   <span style="color: #000000;">0.000000</span>   <span style="color: #000000;">0.500000</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span>  <span style="color: #000000;">0.519504</span><span style="color: #7a0874; font-weight: bold;">&#41;</span></pre></div></div>

<p>redo (  0.403986) es un poco más rápido que callcc (  0.519504). Echándole un vistazo rapido al codigo de la máquina virtual de Ruby se entiende rápidamente el porque. <strong>redo</strong> esta implentado utilizando goto&#8217;s mientras que callcc es una llamada a una función que se encarga de guardar toda la información necesaria en un objeto Continuation, por lo que necesita más tiempo.</p>
<p>Para mas información sobre callcc, su funcionamiento y los continuations:</p>
<ul>
<li><a href="http://www.intertwingly.net/blog/2005/04/13/Continuations-for-Curmudgeons" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.intertwingly.net');">Continuations</a></li>
<li><a href="http://www.madore.org/~david/computers/callcc.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.madore.org');">Callcc</a></li>
<li><a href="http://www.cs.utk.edu/~huangj/cs360/360/notes/Setjmp/lecture.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.cs.utk.edu');">Setjmp/longjmp</a>, funciones en C con las que se puede implementar un comportamiento similar</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.tenako.com/2009/06/03/ruby-callc/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ruby: TCO (Tail Call Optimization)</title>
		<link>http://blog.tenako.com/2009/06/01/ruby-tco-tail-call-optimization/</link>
		<comments>http://blog.tenako.com/2009/06/01/ruby-tco-tail-call-optimization/#comments</comments>
		<pubDate>Mon, 01 Jun 2009 22:21:13 +0000</pubDate>
		<dc:creator>farruco</dc:creator>
				<category><![CDATA[programacion]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[recursividad]]></category>
		<category><![CDATA[tco]]></category>

		<guid isPermaLink="false">http://blog.tenako.com/?p=130</guid>
		<description><![CDATA[Leyendo el libro de Programming Erlang descubrí un concepto que no conocia: funciones tail-recursive.
En esta pagina lo explican bastante bien (entre otros tipos de recursividad), pero basicamente una función tail-recursive es aquella que no tiene ninguna operación pendiente de ejecutar tras la llamada recursiva. En estas funciones, la llamada recursiva puede ser substituida simplemente por [...]]]></description>
			<content:encoded><![CDATA[<p>Leyendo el libro de <a href="http://www.pragprog.com/titles/jaerlang/programming-erlang" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.pragprog.com');" target="_blank">Programming Erlang</a> descubrí un concepto que no conocia: funciones <em>tail-recursive</em>.</p>
<p>En <a href="http://triton.towson.edu/~akayabas/COSC455_Spring2000/Recursion_Iteration.htm" onclick="javascript:pageTracker._trackPageview('/outbound/article/triton.towson.edu');" target="_blank">esta pagina</a> lo explican bastante bien (entre otros tipos de recursividad), pero basicamente una función <em>tail-recursive</em> es aquella que no tiene ninguna operación pendiente de ejecutar tras la llamada recursiva. En estas funciones, la llamada recursiva puede ser substituida simplemente por un salto al comienzo de la función que se llama, con lo que se ahorra espacio en el <em>stack</em>. De esto ultimo se encarga el compilador y es lo que se conoce como <a href="http://c2.com/cgi/wiki?TailCallOptimization" onclick="javascript:pageTracker._trackPageview('/outbound/article/c2.com');" target="_blank">Tail Call Optimization</a> (TCO a partir de ahora).</p>
<p>Así que aparentemente la TCO mola, ¿No?</p>
<p>El problema es que <a href="http://www.ruby-lang.org/es/" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.ruby-lang.org');" targe="_blank">Ruby</a> no tiene implementada  TCO en su maquina virtual con lo que independientemente de como estructuremos nuestras funciones recursivas, siempre estaremos limitados por el tamaño de nuestra Stack.</p>
<p>Pero siempre hay solución para todo y con Ruby, más. En <a href="http://judofyr.net/posts/tailin-ruby.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/judofyr.net');" target="_blank">ésta página</a> dan dos soluciones para tener una pseudo-TCO.</p>
<p>Copio y pego la primera solución:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> <span style="color:#9966CC; font-weight:bold;">Class</span>
  <span style="color:#008000; font-style:italic;"># Sweet stuff!</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> tailcall_optimize<span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#006600; font-weight:bold;">*</span>methods <span style="color:#006600; font-weight:bold;">&#41;</span>
    methods.<span style="color:#9900CC;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> |meth|
      org = instance_method<span style="color:#006600; font-weight:bold;">&#40;</span> meth <span style="color:#006600; font-weight:bold;">&#41;</span>
      define_method<span style="color:#006600; font-weight:bold;">&#40;</span> meth <span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span> |*args|
        <span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#CC00FF; font-weight:bold;">Thread</span>.<span style="color:#9900CC;">current</span><span style="color:#006600; font-weight:bold;">&#91;</span> meth <span style="color:#006600; font-weight:bold;">&#93;</span>
          throw<span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#ff3333; font-weight:bold;">:recurse</span>, args <span style="color:#006600; font-weight:bold;">&#41;</span>
        <span style="color:#9966CC; font-weight:bold;">else</span>
          <span style="color:#CC00FF; font-weight:bold;">Thread</span>.<span style="color:#9900CC;">current</span><span style="color:#006600; font-weight:bold;">&#91;</span> meth <span style="color:#006600; font-weight:bold;">&#93;</span> = org.<span style="color:#9900CC;">bind</span><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#0000FF; font-weight:bold;">self</span> <span style="color:#006600; font-weight:bold;">&#41;</span>
          result = <span style="color:#CC0066; font-weight:bold;">catch</span><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#ff3333; font-weight:bold;">:done</span> <span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
            <span style="color:#CC0066; font-weight:bold;">loop</span> <span style="color:#9966CC; font-weight:bold;">do</span>
              args = <span style="color:#CC0066; font-weight:bold;">catch</span><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#ff3333; font-weight:bold;">:recurse</span> <span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
                throw<span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#ff3333; font-weight:bold;">:done</span>, <span style="color:#CC00FF; font-weight:bold;">Thread</span>.<span style="color:#9900CC;">current</span><span style="color:#006600; font-weight:bold;">&#91;</span> meth <span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">call</span><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#006600; font-weight:bold;">*</span>args <span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#41;</span>
              <span style="color:#9966CC; font-weight:bold;">end</span>
            <span style="color:#9966CC; font-weight:bold;">end</span>
          <span style="color:#9966CC; font-weight:bold;">end</span>
          <span style="color:#CC00FF; font-weight:bold;">Thread</span>.<span style="color:#9900CC;">current</span><span style="color:#006600; font-weight:bold;">&#91;</span> meth <span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#0000FF; font-weight:bold;">nil</span>
          result
        <span style="color:#9966CC; font-weight:bold;">end</span>
      <span style="color:#9966CC; font-weight:bold;">end</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">class</span> TCOTest
  <span style="color:#008000; font-style:italic;"># tail-recursive factorial</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> fact<span style="color:#006600; font-weight:bold;">&#40;</span> n, acc = <span style="color:#006666;">1</span> <span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">if</span> n <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#006666;">2</span> <span style="color:#9966CC; font-weight:bold;">then</span> acc <span style="color:#9966CC; font-weight:bold;">else</span> fact<span style="color:#006600; font-weight:bold;">&#40;</span> n<span style="color:#006600; font-weight:bold;">-</span><span style="color:#006666;">1</span>, n<span style="color:#006600; font-weight:bold;">*</span>acc <span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#008000; font-style:italic;"># length of factorial</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> fact_size<span style="color:#006600; font-weight:bold;">&#40;</span> n <span style="color:#006600; font-weight:bold;">&#41;</span>
    fact<span style="color:#006600; font-weight:bold;">&#40;</span> n <span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">size</span>
  <span style="color:#9966CC; font-weight:bold;">rescue</span>
    $!
  <span style="color:#9966CC; font-weight:bold;">end</span>   
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
t = TCOTest.<span style="color:#9900CC;">new</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># normal method</span>
<span style="color:#CC0066; font-weight:bold;">puts</span> t.<span style="color:#9900CC;">fact_size</span><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#006666;">10000</span> <span style="color:#006600; font-weight:bold;">&#41;</span>  <span style="color:#008000; font-style:italic;"># =&gt; stack level too deep</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># enable tail-call optimization</span>
<span style="color:#9966CC; font-weight:bold;">class</span> TCOTest
  tailcall_optimize <span style="color:#ff3333; font-weight:bold;">:fact</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># tail-call optimized method</span>
<span style="color:#CC0066; font-weight:bold;">puts</span> t.<span style="color:#9900CC;">fact_size</span><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#006666;">10000</span> <span style="color:#006600; font-weight:bold;">&#41;</span>  <span style="color:#008000; font-style:italic;"># =&gt; 14808</span></pre></div></div>

<p>Esta solución consiste en jugar con catch&#8217;s,throw&#8217;s y Thread.current para relanzar el mismo método una y otra vez sin tener que crear un nuevo frame en el Stack, ya que el codigo del metodo se encuentra definido en un bloque y por tanto reutiliza el codigo. </p>
<p>La segunda opción:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">def</span> fib<span style="color:#006600; font-weight:bold;">&#40;</span>i, n = <span style="color:#006666;">1</span>, result = 0<span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">if</span> i == <span style="color:#006600; font-weight:bold;">-</span><span style="color:#006666;">1</span>
    result
  <span style="color:#9966CC; font-weight:bold;">else</span>
    i, n, result = i <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#006666;">1</span>, n <span style="color:#006600; font-weight:bold;">+</span> result, n
    <span style="color:#9966CC; font-weight:bold;">redo</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
fib<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">10000</span><span style="color:#006600; font-weight:bold;">&#41;</span></pre></div></div>

<p>Esta solución consiste en hacer uso de la palabra <a href="http://www.rubyist.net/~slagell/ruby/control.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.rubyist.net');" target="_blank">redo</a> la cual reinicia la ejecución de cualquier loop o iterador. El problema con redo es que, como acabo de decir, solo se puede utilizar en loops o iteradores y el método fib anterior no es ninguno de ellos. Por lo que el autor de la página de que se extrajeron las soluciones dice:</p>
<blockquote><p>Unfortunately, “The redo statement restarts the current iteration of a loop or iterator”, so it only throws a LocalJumpError</p></blockquote>
<p><img src="http://blog.tenako.com/wp-content/uploads/2009/06/ruby_spartan1.png" alt="ruby_spartan1" title="ruby_spartan1" width="550" height="343" class="aligncenter size-full wp-image-153" /></p>
<p>Gracias señor espartano. </p>
<p>Así es, esto es Ruby y siempre hay un workaround para todo. En este caso, consiste en crear un nuevo método cuyo cuerpo este contenido en un bloque.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby ruby" style="font-family:monospace;">define_method<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:acc</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span> |i, n, result|
  <span style="color:#9966CC; font-weight:bold;">if</span> i == <span style="color:#006600; font-weight:bold;">-</span><span style="color:#006666;">1</span>
    result
  <span style="color:#9966CC; font-weight:bold;">else</span>
    i, n, result = i <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#006666;">1</span>, n <span style="color:#006600; font-weight:bold;">+</span> result, n
    <span style="color:#9966CC; font-weight:bold;">redo</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">def</span> fib<span style="color:#006600; font-weight:bold;">&#40;</span>i<span style="color:#006600; font-weight:bold;">&#41;</span>
  acc<span style="color:#006600; font-weight:bold;">&#40;</span>i, <span style="color:#006666;">1</span>, 0<span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
fib<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">10000</span><span style="color:#006600; font-weight:bold;">&#41;</span>  <span style="color:#008000; font-style:italic;"># Yeah!</span></pre></div></div>

<p>Y ya podemos utilizar redo. Fin!!</p>
<p>Para mas información, hay un thread en esta lista de correo en el que debaten sobre este tema: <a href="http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/171075" onclick="javascript:pageTracker._trackPageview('/outbound/article/blade.nagaokaut.ac.jp');" target="_blank">Ruby tail recursion</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.tenako.com/2009/06/01/ruby-tco-tail-call-optimization/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ruby: Expirar los mensajes de Starling en 3 comodos pasos</title>
		<link>http://blog.tenako.com/2009/03/20/expirar-mensajes-starling/</link>
		<comments>http://blog.tenako.com/2009/03/20/expirar-mensajes-starling/#comments</comments>
		<pubDate>Fri, 20 Mar 2009 17:12:12 +0000</pubDate>
		<dc:creator>farruco</dc:creator>
				<category><![CDATA[programacion]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[Add new tag]]></category>
		<category><![CDATA[expiry]]></category>
		<category><![CDATA[starling]]></category>

		<guid isPermaLink="false">http://blog.tenako.com/?p=113</guid>
		<description><![CDATA[Si te pasa como a mi, que quieres almacenar mensajes en el starling pero que algunos de ellos lleven &#8220;fecha de caducidad&#8220;, sigue los siguiente pasos.

Paso 1 : Abrir en un editor el fichero handler.rb perteneciente a la gema starling-starling.
Paso 2 : En el método Handler#set_data añadir la siguiente linea justo antes de hacer el [...]]]></description>
			<content:encoded><![CDATA[<p>Si te pasa como a mi, que quieres almacenar mensajes en el starling pero que algunos de ellos lleven &#8220;<a href="http://www.deveiate.org/code/Ruby-MemCache/classes/MemCache.html#M000009" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.deveiate.org');">fecha de caducidad</a>&#8220;, sigue los siguiente pasos.</p>
<ul>
<li><strong>Paso 1 :</strong> Abrir en un editor el fichero handler.rb perteneciente a la gema <a href="http://github.com/starling/starling/tree/master" onclick="javascript:pageTracker._trackPageview('/outbound/article/github.com');">starling-starling</a>.</li>
<li><strong>Paso 2 :</strong> En el método <em>Handler#set_data</em> añadir la siguiente linea justo antes de hacer el pack para generar la variable <em>internal_data</em>.</li>

<div class="wp_syntax"><div class="code"><pre class="ruby ruby" style="font-family:monospace;">  ...
  <span style="color:#9900CC;">expiry</span> = <span style="color:#CC00FF; font-weight:bold;">Time</span>.<span style="color:#9900CC;">now</span>.<span style="color:#9900CC;">to_i</span> <span style="color:#006600; font-weight:bold;">+</span> expiry.<span style="color:#9900CC;">to_i</span> <span style="color:#9966CC; font-weight:bold;">unless</span> expiry.<span style="color:#9900CC;">to_i</span> == 0
  ...</pre></div></div>

<li><strong>Paso 3 :</strong> Guarda y re-arranca el starling.Todo debería de ir como la seda.</li>
</ul>
<p>Con esto, lo único que hemos hecho es corregir un pequeño bug que hay en <em>Handler#get</em> ya que en este método solo se devuelve un mensaje si su expiry es 0 o si expiry es mayor que now (now en este contexto es Time.now.to_i ). El fallo viene de comparar a now (valor <a href="http://en.wikipedia.org/wiki/Unix_time" onclick="javascript:pageTracker._trackPageview('/outbound/article/en.wikipedia.org');">unix time</a>) con expiry el cual es solo un offset desde el momento en el que decidimos guardar un mensaje en starling.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby ruby" style="font-family:monospace;">  ...
  <span style="color:#9966CC; font-weight:bold;">break</span> <span style="color:#9966CC; font-weight:bold;">if</span> expiry == 0 || expiry <span style="color:#006600; font-weight:bold;">&gt;</span>= now
&nbsp;
  <span style="color:#0066ff; font-weight:bold;">@expiry_stats</span><span style="color:#006600; font-weight:bold;">&#91;</span>key<span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">+</span>= <span style="color:#006666;">1</span>
  expiry, data = <span style="color:#0000FF; font-weight:bold;">nil</span>
  ...</pre></div></div>

<p>Con la linea que añadimos al método <em>Handler#set_data</em> forzamos que la comparación sea entre dos valores unix time.Uno refiriéndose al momento actual (now) y otro al momento en el que expirara el mensaje (la suma de Time.now.to_i en el momento del almacenarlo y el tiempo de vida del mensaje).</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.tenako.com/2009/03/20/expirar-mensajes-starling/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Rails: Observar un modelo desde un plugin == problemas</title>
		<link>http://blog.tenako.com/2008/11/16/rails-observar-un-modelo-desde-un-plugin-problemas/</link>
		<comments>http://blog.tenako.com/2008/11/16/rails-observar-un-modelo-desde-un-plugin-problemas/#comments</comments>
		<pubDate>Sun, 16 Nov 2008 23:52:35 +0000</pubDate>
		<dc:creator>farruco</dc:creator>
				<category><![CDATA[programacion]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[desarrollo]]></category>
		<category><![CDATA[observers]]></category>
		<category><![CDATA[plugin]]></category>

		<guid isPermaLink="false">http://blog.tenako.com/?p=46</guid>
		<description><![CDATA[Rails implementa el patron observador para permitir observar un modelo y responder así los diferentes estados que puede atravesar un objeto de dicho modelo.
Actualmente estoy trabajando en un proyecto donde es necesario que dos aplicaciones realizadas  en Rails se comuniquen entre si mediante mediante Rest.Para conseguir esto, una de las aplicaciones incluye un plugin [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.rubyonrails.org/" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.rubyonrails.org');">Rails</a> <a href="http://api.rubyonrails.org/classes/ActiveRecord/Observer.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/api.rubyonrails.org');">implementa</a> el <a href="http://en.wikipedia.org/wiki/Observer_pattern" onclick="javascript:pageTracker._trackPageview('/outbound/article/en.wikipedia.org');">patron observador</a> para permitir observar un modelo y responder así los diferentes estados que puede atravesar un objeto de dicho modelo.</p>
<p>Actualmente estoy trabajando en un proyecto donde es necesario que dos aplicaciones realizadas  en Rails se comuniquen entre si mediante mediante <a href="http://en.wikipedia.org/wiki/Representational_State_Transfer" onclick="javascript:pageTracker._trackPageview('/outbound/article/en.wikipedia.org');">Rest</a>.Para conseguir esto, una de las aplicaciones incluye un plugin (proxy) en la otra.En este plugin se encarga de lo siguiente:</p>
<ul>
<li> Se definen los datos necesarios para esta comunicacion entre aplicaciones como así requiere <a href="http://api.rubyonrails.org/classes/ActiveResource/Base.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/api.rubyonrails.org');">ActiveResource::Base</a></li>
<li>Se registra un observador que observara (valga la redundancia)  uno de los modelos en la aplicación receptora el plugin</li>
</ul>
<p>Antes de continuar con este post, tengo que confesar una cosilla, observar un modelo desde un plugin es un problema, si y solo si  se hace en modo <strong>desarrollo</strong>.¿Y por qué?</p>
<p>Si no te interesa saber el porque de los problemas y has llegado hasta aqui buscando una solucion, con indicar a Rails que recargue los plugins en cada petición tendrás el asunto resuelto.</p>
<p>Para ello sigue los siguientes pasos:</p>
<p><strong>1º. Indicar a Rails que quieres recargar los plugins</strong></p>
<p>En <strong>config/environment.rb</strong> añade esta linea:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby ruby" style="font-family:monospace;">config.<span style="color:#9900CC;">reload_plugins</span> = <span style="color:#0000FF; font-weight:bold;">true</span></pre></div></div>

<p>Con esto lo único que hacemos en realidad, es evitar que el path /lib de cada plugin sea incluido en <strong>Dependencies.load_once_paths</strong></p>
<p>Pero esto puede que no nos arregle nuestro problema y para muestra un ejemplo:</p>
<p>Arrancare el <a href="http://www.webrick.org/" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.webrick.org');">webrick</a> en modo debug con un breakpoint en el método dispatch del fichero dispatcher.rb, método invocado para cada petición.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">def</span> dispatch<span style="color:#006600; font-weight:bold;">&#40;</span>cgi = <span style="color:#0000FF; font-weight:bold;">nil</span>, session_options = <span style="color:#6666ff; font-weight:bold;">CgiRequest::DEFAULT_SESSION_OPTIONS</span>, output = <span style="color:#ff6633; font-weight:bold;">$stdout</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    debugger
    new<span style="color:#006600; font-weight:bold;">&#40;</span>output<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">dispatch_cgi</span><span style="color:#006600; font-weight:bold;">&#40;</span>cgi, session_options<span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Arrancamos y enviamos una peticion:</p>

<div class="wp_syntax"><div class="code"><pre class="bash bash" style="font-family:monospace;">=<span style="color: #000000; font-weight: bold;">&gt;</span> Booting WEBrick...
=<span style="color: #000000; font-weight: bold;">&gt;</span> Debugger enabled
=<span style="color: #000000; font-weight: bold;">&gt;</span> Rails 2.1.1 application started on http:<span style="color: #000000; font-weight: bold;">//</span>events.trabenet.local:<span style="color: #000000;">3001</span>
=<span style="color: #000000; font-weight: bold;">&gt;</span> Ctrl-C to shutdown server; call with <span style="color: #660033;">--help</span> <span style="color: #000000; font-weight: bold;">for</span> options
<span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #000000;">2008</span>-<span style="color: #000000;">11</span>-<span style="color: #000000;">16</span> <span style="color: #000000;">21</span>:<span style="color: #000000;">37</span>:<span style="color: #000000;">24</span><span style="color: #7a0874; font-weight: bold;">&#93;</span> INFO  WEBrick 1.3.1
<span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #000000;">2008</span>-<span style="color: #000000;">11</span>-<span style="color: #000000;">16</span> <span style="color: #000000;">21</span>:<span style="color: #000000;">37</span>:<span style="color: #000000;">24</span><span style="color: #7a0874; font-weight: bold;">&#93;</span> INFO  ruby 1.8.7 <span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000;">2008</span>-08-08<span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span>i686-darwin8<span style="color: #7a0874; font-weight: bold;">&#93;</span>
<span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #000000;">2008</span>-<span style="color: #000000;">11</span>-<span style="color: #000000;">16</span> <span style="color: #000000;">21</span>:<span style="color: #000000;">37</span>:<span style="color: #000000;">25</span><span style="color: #7a0874; font-weight: bold;">&#93;</span> INFO  WEBrick::HTTPServer<span style="color: #666666; font-style: italic;">#start: pid=1394 port=3001</span>
<span style="color: #000000; font-weight: bold;">/</span>opt<span style="color: #000000; font-weight: bold;">/</span><span style="color: #7a0874; font-weight: bold;">local</span><span style="color: #000000; font-weight: bold;">/</span>lib<span style="color: #000000; font-weight: bold;">/</span>ruby<span style="color: #000000; font-weight: bold;">/</span>gems<span style="color: #000000; font-weight: bold;">/</span><span style="color: #000000;">1.8</span><span style="color: #000000; font-weight: bold;">/</span>gems<span style="color: #000000; font-weight: bold;">/</span>actionpack-2.1.1<span style="color: #000000; font-weight: bold;">/</span>lib<span style="color: #000000; font-weight: bold;">/</span>action_controller<span style="color: #000000; font-weight: bold;">/</span>dispatcher.rb:<span style="color: #000000;">36</span>
new<span style="color: #7a0874; font-weight: bold;">&#40;</span>output<span style="color: #7a0874; font-weight: bold;">&#41;</span>.dispatch_cgi<span style="color: #7a0874; font-weight: bold;">&#40;</span>cgi, session_options<span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #7a0874; font-weight: bold;">&#40;</span>rdb:<span style="color: #000000;">2</span><span style="color: #7a0874; font-weight: bold;">&#41;</span></pre></div></div>

<p>El plugin del que tratamos declara una constante, EventObserver. Veamos si existe:</p>

<div class="wp_syntax"><div class="code"><pre class="bash bash" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">&#40;</span>rdb:<span style="color: #000000;">2</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> EventObserver
EventObserver
<span style="color: #7a0874; font-weight: bold;">&#40;</span>rdb:<span style="color: #000000;">2</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> EventObserver.object_id
<span style="color: #000000;">25840630</span></pre></div></div>

<p>Perfecto.</p>
<p>Como en mi config/environment.rb indico que quiere recargar mis plugins, tenemos que:</p>

<div class="wp_syntax"><div class="code"><pre class="bash bash" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">&#40;</span>rdb:<span style="color: #000000;">2</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> Dependencies.load_once_paths
<span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #7a0874; font-weight: bold;">&#93;</span></pre></div></div>

<p>Y los load_paths son:</p>

<div class="wp_syntax"><div class="code"><pre class="bash bash" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">&#40;</span>rdb:<span style="color: #000000;">2</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> pp Dependencies.load_paths
<span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #ff0000;">&quot;/Users/madtrick/programacion/trabesoluciones/trabenet-sources/trabenet-events/app/controllers/&quot;</span>,
 <span style="color: #ff0000;">&quot;/Users/madtrick/programacion/trabesoluciones/trabenet-sources/trabenet-events/app&quot;</span>,
 <span style="color: #ff0000;">&quot;/Users/madtrick/programacion/trabesoluciones/trabenet-sources/trabenet-events/app/models&quot;</span>,
 <span style="color: #ff0000;">&quot;/Users/madtrick/programacion/trabesoluciones/trabenet-sources/trabenet-events/app/controllers&quot;</span>,
 <span style="color: #ff0000;">&quot;/Users/madtrick/programacion/trabesoluciones/trabenet-sources/trabenet-events/app/helpers&quot;</span>,
 <span style="color: #ff0000;">&quot;/Users/madtrick/programacion/trabesoluciones/trabenet-sources/trabenet-events/config&quot;</span>,
 <span style="color: #ff0000;">&quot;/Users/madtrick/programacion/trabesoluciones/trabenet-sources/trabenet-events/vendor&quot;</span>,
 <span style="color: #ff0000;">&quot;/opt/local/lib/ruby/gems/1.8/gems/rails-2.1.1/lib/../builtin/rails_info/&quot;</span>,
 <span style="color: #ff0000;">&quot;/Users/madtrick/programacion/trabesoluciones/trabenet-sources/trabenet-events/vendor/plugins/background/lib&quot;</span>,
 <span style="color: #ff0000;">&quot;/Users/madtrick/programacion/trabesoluciones/trabenet-sources/trabenet-events/vendor/plugins/localization-with-gettext/lib&quot;</span>,
 <span style="color: #ff0000;">&quot;/Users/madtrick/programacion/trabesoluciones/trabenet-sources/trabenet-events/vendor/plugins/localized_url_helpers/lib&quot;</span>,
 <span style="color: #ff0000;">&quot;/opt/local/lib/ruby/gems/1.8/gems/mbleigh-acts-as-taggable-on-1.0.2/lib&quot;</span>,
 <span style="color: #ff0000;">&quot;/Users/madtrick/programacion/trabesoluciones/trabenet-sources/trabenet-events/vendor/plugins/thinking-sphinx/lib&quot;</span>,
 <span style="color: #ff0000;">&quot;/Users/madtrick/programacion/trabesoluciones/trabenet-sources/trabenet-events/vendor/plugins/trabenet-auth/lib&quot;</span>,
 <span style="color: #ff0000;">&quot;/Users/madtrick/programacion/trabesoluciones/trabenet-sources/trabenet-events/vendor/plugins/trabenet-core/lib&quot;</span>,
 <span style="color: #ff0000;">&quot;/Users/madtrick/programacion/trabesoluciones/trabenet-sources/trabenet-events/vendor/plugins/trabenet-people-proxy/lib&quot;</span>,
 <span style="color: #ff0000;">&quot;/Users/madtrick/programacion/trabesoluciones/trabenet-sources/trabenet-events/vendor/plugins/trabenet_subscriptions_proxy/lib&quot;</span>,
 <span style="color: #ff0000;">&quot;/opt/local/lib/ruby/gems/1.8/gems/will_paginate-2.2.2/lib&quot;</span><span style="color: #7a0874; font-weight: bold;">&#93;</span></pre></div></div>

<p>Por tanto en cada nueva petición los plugins serán candidatos a ser recargados.</p>
<p>Veamos si esto es así con otra petición:</p>

<div class="wp_syntax"><div class="code"><pre class="bash bash" style="font-family:monospace;">127.0.0.1 - - <span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #000000;">16</span><span style="color: #000000; font-weight: bold;">/</span>Nov<span style="color: #000000; font-weight: bold;">/</span><span style="color: #000000;">2008</span>:<span style="color: #000000;">22</span>:00:<span style="color: #000000;">21</span> CET<span style="color: #7a0874; font-weight: bold;">&#93;</span> <span style="color: #ff0000;">&quot;POST /events.xml HTTP/1.1&quot;</span> <span style="color: #000000;">201</span> <span style="color: #000000;">1</span>
- -<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #000000; font-weight: bold;">/</span>events.xml
<span style="color: #000000; font-weight: bold;">/</span>opt<span style="color: #000000; font-weight: bold;">/</span><span style="color: #7a0874; font-weight: bold;">local</span><span style="color: #000000; font-weight: bold;">/</span>lib<span style="color: #000000; font-weight: bold;">/</span>ruby<span style="color: #000000; font-weight: bold;">/</span>gems<span style="color: #000000; font-weight: bold;">/</span><span style="color: #000000;">1.8</span><span style="color: #000000; font-weight: bold;">/</span>gems<span style="color: #000000; font-weight: bold;">/</span>actionpack-2.1.1<span style="color: #000000; font-weight: bold;">/</span>lib<span style="color: #000000; font-weight: bold;">/</span>action_controller<span style="color: #000000; font-weight: bold;">/</span>dispatcher.rb:<span style="color: #000000;">36</span>
new<span style="color: #7a0874; font-weight: bold;">&#40;</span>output<span style="color: #7a0874; font-weight: bold;">&#41;</span>.dispatch_cgi<span style="color: #7a0874; font-weight: bold;">&#40;</span>cgi, session_options<span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #7a0874; font-weight: bold;">&#40;</span>rdb:<span style="color: #000000;">11</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> EventObserver.object_id
<span style="color: #000000;">25840630</span></pre></div></div>

<p>Pues no, aquí no se recarga nada!! porque como podemos apreciar , el object_id de la constante es el mismo que el de la primera petición, es decir son el mismo objeto.</p>
<p><a href="http://blog.tenako.com/wp-content/uploads/2008/11/zpatontao.jpg" ><img src="http://blog.tenako.com/wp-content/uploads/2008/11/zpatontao-270x300.jpg" alt="" title="zpatontao" width="270" height="300" class="aligncenter size-medium wp-image-48" /></a></p>
<p><strong>2º.Segundo paso de la solución,descargar las constantes del entorno</strong></p>
<p>La explicación a que el objeto representado por EventObserver sea el mismo esto es la siguiente:</p>
<p>Para empezar hay que tener en cuanta que para que una constante definida en un plugin tenga validez en Rails es necesario que ocurra una de las siguientes posibilidades:</p>
<ul>
<li>Cuando se inicializa el entorno de Rails, para cada plugin se evalúa su fichero <strong>init.rb</strong> de forma que podemos utilizar llamadas a <em>require</em> para incluir el código  contenido en el directorio /lib del plugin (y por tanto las constantes de este), en Rails.
</li>
<li>Que las constantes sean cargadas de forma dinámica como ya explique en <a href="http://blog.tenako.com/2008/11/14/rails-carga-dinamica-de-constantes/" >este post</a>, de forma que cada una de estas constantes incluidas de esta forma pasa a formar parte del array <strong>Dependencies.autoloaded_constants</strong>.Esto ultimo es importante.</li>
</ul>
<p>La importancia de la forma en la que se carga una constante en Rails, reside en <strong>que</strong> es lo que se <strong>recarga</strong> en cada petición y que es lo que se <strong>descarga</strong> tras cada peticion.Tras cada petición (si estamos en modo de desarrollo) se enviara un mensaje a <strong>Dependencies.clear</strong>.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">def</span> clear
      log_call
      loaded.<span style="color:#9900CC;">clear</span>
      remove_unloadable_constants!
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>La parte interesante de Dependencies.clear es la llamada al método <strong>remove_unloadable_constants!</strong></p>

<div class="wp_syntax"><div class="code"><pre class="ruby ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">def</span> remove_unloadable_constants!
      autoloaded_constants.<span style="color:#9900CC;">each</span> <span style="color:#006600; font-weight:bold;">&#123;</span> |const| remove_constant const <span style="color:#006600; font-weight:bold;">&#125;</span>
      autoloaded_constants.<span style="color:#9900CC;">clear</span>
      explicitly_unloadable_constants.<span style="color:#9900CC;">each</span> <span style="color:#006600; font-weight:bold;">&#123;</span> |const| remove_constant const <span style="color:#006600; font-weight:bold;">&#125;</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>En este método se borra la constante indicada del modulo o clase correspondiente. Como se puede apreciar se borraran tanto las constante &#8220;autocargadas&#8221; como las indicadas explicitaménte en <strong>Dependencies.explicitly_unloadable_constants</strong>.</p>
<p>A pesar de haber indicado en nuestro environment.rb que queríamos recargar los plugins (config.reload_plugins=true); para cada petición no se volverá a evaluar el fichero init.rb de cada plugin y  por tanto, si nuestras constantes se cargan en Rails mediante llamadas a <strong>require</strong> (no existirán en el array Dependencies.autoloaded_constants) ; estas no volverán a ser cargadas debido a  que no habrá necesidad de ello al no haber sido descargadas en Dependencies.explicitly_unloadable_constants.Para solucionar esto podemos optar por una de estas opciones:</p>
<ul>
<li>No utilizar requires y dejar la carga de las constantes en manos de los mecanismos de Rails</li>
<li>Hacer uso de Depedencies.explicitly_unloadable_constants, indicando en dicho array las constantes que queremos que se descarguen tras cada petición</li>
</ul>
<p>Volviendo a nuestro ejemplo, probemos una de estas opciones.Utilizaremos Depedencies.explicitly_unloadable_constants.</p>
<p>En mi caso, defino las constantes que quiero que se descargen en el init.rb del plugin (por eso de tener todo juntito : ) ).</p>

<div class="wp_syntax"><div class="code"><pre class="ruby ruby" style="font-family:monospace;">Dependencies.<span style="color:#9900CC;">explicitly_unloadable_constants</span> = <span style="color:#996600;">'EventObserver'</span></pre></div></div>

<p>Y lo probamos de nuevo con webrick:</p>

<div class="wp_syntax"><div class="code"><pre class="bash bash" style="font-family:monospace;">=<span style="color: #000000; font-weight: bold;">&gt;</span> Booting WEBrick...
=<span style="color: #000000; font-weight: bold;">&gt;</span> Debugger enabled
=<span style="color: #000000; font-weight: bold;">&gt;</span> Rails 2.1.1 application started on http:<span style="color: #000000; font-weight: bold;">//</span>events.trabenet.local:<span style="color: #000000;">3001</span>
=<span style="color: #000000; font-weight: bold;">&gt;</span> Ctrl-C to shutdown server; call with <span style="color: #660033;">--help</span> <span style="color: #000000; font-weight: bold;">for</span> options
<span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #000000;">2008</span>-<span style="color: #000000;">11</span>-<span style="color: #000000;">17</span> 00:01:<span style="color: #000000;">15</span><span style="color: #7a0874; font-weight: bold;">&#93;</span> INFO  WEBrick 1.3.1
<span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #000000;">2008</span>-<span style="color: #000000;">11</span>-<span style="color: #000000;">17</span> 00:01:<span style="color: #000000;">15</span><span style="color: #7a0874; font-weight: bold;">&#93;</span> INFO  ruby 1.8.7 <span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000;">2008</span>-08-08<span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span>i686-darwin8<span style="color: #7a0874; font-weight: bold;">&#93;</span>
<span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #000000;">2008</span>-<span style="color: #000000;">11</span>-<span style="color: #000000;">17</span> 00:01:<span style="color: #000000;">15</span><span style="color: #7a0874; font-weight: bold;">&#93;</span> INFO  WEBrick::HTTPServer<span style="color: #666666; font-style: italic;">#start: pid=1442 port=3001</span>
<span style="color: #000000; font-weight: bold;">/</span>opt<span style="color: #000000; font-weight: bold;">/</span><span style="color: #7a0874; font-weight: bold;">local</span><span style="color: #000000; font-weight: bold;">/</span>lib<span style="color: #000000; font-weight: bold;">/</span>ruby<span style="color: #000000; font-weight: bold;">/</span>gems<span style="color: #000000; font-weight: bold;">/</span><span style="color: #000000;">1.8</span><span style="color: #000000; font-weight: bold;">/</span>gems<span style="color: #000000; font-weight: bold;">/</span>actionpack-2.1.1<span style="color: #000000; font-weight: bold;">/</span>lib<span style="color: #000000; font-weight: bold;">/</span>action_controller<span style="color: #000000; font-weight: bold;">/</span>dispatcher.rb:<span style="color: #000000;">36</span>
new<span style="color: #7a0874; font-weight: bold;">&#40;</span>output<span style="color: #7a0874; font-weight: bold;">&#41;</span>.dispatch_cgi<span style="color: #7a0874; font-weight: bold;">&#40;</span>cgi, session_options<span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #7a0874; font-weight: bold;">&#40;</span>rdb:<span style="color: #000000;">2</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> EventObserver.object_id
<span style="color: #000000;">25840560</span></pre></div></div>

<p>Lanzamos otra petición.</p>

<div class="wp_syntax"><div class="code"><pre class="bash bash" style="font-family:monospace;">127.0.0.1 - - <span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #000000;">17</span><span style="color: #000000; font-weight: bold;">/</span>Nov<span style="color: #000000; font-weight: bold;">/</span><span style="color: #000000;">2008</span>:00:01:<span style="color: #000000;">17</span> CET<span style="color: #7a0874; font-weight: bold;">&#93;</span> <span style="color: #ff0000;">&quot;POST /events.xml HTTP/1.1&quot;</span> <span style="color: #000000;">201</span> <span style="color: #000000;">1</span>
- -<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #000000; font-weight: bold;">/</span>events.xml
<span style="color: #000000; font-weight: bold;">/</span>opt<span style="color: #000000; font-weight: bold;">/</span><span style="color: #7a0874; font-weight: bold;">local</span><span style="color: #000000; font-weight: bold;">/</span>lib<span style="color: #000000; font-weight: bold;">/</span>ruby<span style="color: #000000; font-weight: bold;">/</span>gems<span style="color: #000000; font-weight: bold;">/</span><span style="color: #000000;">1.8</span><span style="color: #000000; font-weight: bold;">/</span>gems<span style="color: #000000; font-weight: bold;">/</span>actionpack-2.1.1<span style="color: #000000; font-weight: bold;">/</span>lib<span style="color: #000000; font-weight: bold;">/</span>action_controller<span style="color: #000000; font-weight: bold;">/</span>dispatcher.rb:<span style="color: #000000;">36</span>
new<span style="color: #7a0874; font-weight: bold;">&#40;</span>output<span style="color: #7a0874; font-weight: bold;">&#41;</span>.dispatch_cgi<span style="color: #7a0874; font-weight: bold;">&#40;</span>cgi, session_options<span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #7a0874; font-weight: bold;">&#40;</span>rdb:<span style="color: #000000;">11</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> EventObserver.object_id
<span style="color: #000000;">27418300</span></pre></div></div>

<p>Como se puede apreciar en esta ocasión son objetos distintos y por tanto realmente se recargado la constante.</p>
<p>Tras hacer esto, ya podemos observar con tranquilidad a nuestros modelos desde el plugin.</p>
<p>A partir de aquí voy a explicar el porque de la necesidad de recargar el contenido de nuestros plugins para poder observar a un modelo en modo de desarrollo.</p>
<p>Como explique antes, si no se recarga el contenido de nuestros plugins y en concreto la clase donde definimos el observador del modelo, tendremos un problema.¿Y por qué?</p>
<p>Primero , algunas cosillas a tener en consideración:</p>
<ul>
<li>Los Observadores en Rails utilizan el <a href="http://en.wikipedia.org/wiki/Singleton_pattern" onclick="javascript:pageTracker._trackPageview('/outbound/article/en.wikipedia.org');">patrón Singleton</a></li>
<li>Donde se instancian los observadores</li>
</ul>
<p>Empezaremos por el segundo punto.</p>
<p>En Rails, existen dos puntos prefijados donde se instancian los observadores correspondientes a cada modelo.El primero es en el fichero <strong>initializer.rb</strong> en el metodo de clase <strong>process</strong> donde se invoca el metodo load_observers</p>

<div class="wp_syntax"><div class="code"><pre class="ruby ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">def</span> process
...
<span style="color:#9900CC;">load_observers</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Con load_observers como sigue,</p>

<div class="wp_syntax"><div class="code"><pre class="ruby ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">def</span> load_observers
      <span style="color:#9966CC; font-weight:bold;">if</span> gems_dependencies_loaded <span style="color:#006600; font-weight:bold;">&amp;&amp;</span> configuration.<span style="color:#9900CC;">frameworks</span>.<span style="color:#9966CC; font-weight:bold;">include</span>?<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:active_record</span><span style="color:#006600; font-weight:bold;">&#41;</span>
        <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>.<span style="color:#9900CC;">instantiate_observers</span>
      <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>En ActiveRecord::Base.instantiate_observers crearemos para cada modelo sus observadores y será aquí donde comienzen nuestros quebraderos de cabeza.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">def</span> instantiate_observers
        <span style="color:#0000FF; font-weight:bold;">return</span> <span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#0066ff; font-weight:bold;">@observers</span>.<span style="color:#9900CC;">blank</span>?
        <span style="color:#0066ff; font-weight:bold;">@observers</span>.<span style="color:#9900CC;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> |observer|
          <span style="color:#9966CC; font-weight:bold;">if</span> observer.<span style="color:#9900CC;">respond_to</span>?<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:to_sym</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#008000; font-style:italic;"># Symbol or String</span>
            temp = observer.<span style="color:#9900CC;">to_s</span>.<span style="color:#9900CC;">camelize</span>.<span style="color:#9900CC;">constantize</span>
            temp.<span style="color:#9900CC;">instance</span>
          <span style="color:#9966CC; font-weight:bold;">elsif</span> observer.<span style="color:#9900CC;">respond_to</span>?<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:instance</span><span style="color:#006600; font-weight:bold;">&#41;</span>
            observer.<span style="color:#9900CC;">instance</span>
          <span style="color:#9966CC; font-weight:bold;">else</span>
            <span style="color:#CC0066; font-weight:bold;">raise</span> <span style="color:#CC00FF; font-weight:bold;">ArgumentError</span>, <span style="color:#996600;">&quot;#{observer} must be a lowercase, underscored class name (or an instance of the class itself) responding to the instance method. Example: Person.observers = :big_brother # calls BigBrother.instance&quot;</span>
          <span style="color:#9966CC; font-weight:bold;">end</span>
        <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>POR TERMINAR, lo hare en otro post : )</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.tenako.com/2008/11/16/rails-observar-un-modelo-desde-un-plugin-problemas/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ruby,Rails: &#8220;metodos encadenados&#8221;</title>
		<link>http://blog.tenako.com/2008/09/19/rubyrails-metodos-encadenados/</link>
		<comments>http://blog.tenako.com/2008/09/19/rubyrails-metodos-encadenados/#comments</comments>
		<pubDate>Fri, 19 Sep 2008 16:13:15 +0000</pubDate>
		<dc:creator>farruco</dc:creator>
				<category><![CDATA[programacion]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[cadena]]></category>
		<category><![CDATA[metodos]]></category>

		<guid isPermaLink="false">http://blog.tenako.com/?p=7</guid>
		<description><![CDATA[Una de las cosas que mas me gustan de Ruby es su dinamismo y la posibilidad de &#8220;abrir&#8221; las clases y modulos para añadir o redefinir metodos totalmente dinamicamente y en tiempo de ejecucion.
Esta funcionalidad junto con la posibilidad de saber cuando un modulo ha sido incluido en una clase nos permite añadir funcionalidad a [...]]]></description>
			<content:encoded><![CDATA[<p>Una de las cosas que mas me gustan de <a href="http://www.ruby-lang.org/es/" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.ruby-lang.org');" target="_blank">Ruby</a> es su dinamismo y la posibilidad de &#8220;abrir&#8221; las clases y modulos para añadir o redefinir metodos totalmente dinamicamente y en tiempo de ejecucion.</p>
<p>Esta funcionalidad junto con la posibilidad de saber cuando un modulo ha sido incluido en una clase nos permite añadir funcionalidad a las clases que incluyen el modulo sin que estan tengan que percibirlo.</p>
<p>Un ejemplo:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> <span style="color:#9966CC; font-weight:bold;">Module</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> included<span style="color:#006600; font-weight:bold;">&#40;</span>base<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#CC0066; font-weight:bold;">p</span> <span style="color:#996600;">&quot;Included module &quot;</span> <span style="color:#006600; font-weight:bold;">+</span> name
&nbsp;
    without = <span style="color:#996600;">&quot;test_method_#{name}_without_filters&quot;</span>.<span style="color:#9900CC;">to_sym</span>
    with =<span style="color:#996600;">&quot;test_method_#{name}_with_filters&quot;</span>.<span style="color:#9900CC;">to_sym</span>
    base.<span style="color:#9900CC;">class_eval</span> <span style="color:#9966CC; font-weight:bold;">do</span>
      alias_method without, <span style="color:#ff3333; font-weight:bold;">:test_method</span>
      alias_method <span style="color:#ff3333; font-weight:bold;">:test_method</span>, with
    <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Lo que he hecho es redefinir el metodo <a href="http://www.ruby-doc.org/core/classes/Module.html#M001683" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.ruby-doc.org');" target="_blank">included</a> para que todos los modulos indiquen que ha sido incluidos y que hagan un alias sobre el metodo &#8220;<em>test_method</em>&#8220;.</p>
<blockquote><p>Hay que tener en cuenta que <a href="http://www.ruby-doc.org/core/classes/Module.html#M001676" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.ruby-doc.org');" target="_blank">alias_method</a> no sobreescribe el metodo original, sino que hace una guarda una referencia a este, de forma que aun pueda ser invocado.</p></blockquote>

<div class="wp_syntax"><div class="code"><pre class="ruby ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">module</span> A
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> test_method_A_with_filters
    <span style="color:#CC0066; font-weight:bold;">p</span> <span style="color:#996600;">&quot;Doing something really important in module A&quot;</span>
    test_method_A_without_filters
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">module</span> B
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> test_method_B_with_filters
    <span style="color:#CC0066; font-weight:bold;">p</span> <span style="color:#996600;">&quot;Doing something really important in module B&quot;</span>
    test_method_B_without_filters
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
&nbsp;
<span style="color:#9966CC; font-weight:bold;">class</span> <span style="color:#CC00FF; font-weight:bold;">Test</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> test_method
      <span style="color:#CC0066; font-weight:bold;">p</span> <span style="color:#996600;">&quot;Inside method of class A&quot;</span>
&nbsp;
      <span style="color:#CC0066; font-weight:bold;">p</span> <span style="color:#996600;">&quot;Backtrace:&quot;</span>
      <span style="color:#CC0066; font-weight:bold;">caller</span>.<span style="color:#9900CC;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> |text| <span style="color:#CC0066; font-weight:bold;">p</span> text <span style="color:#9966CC; font-weight:bold;">end</span>
      <span style="color:#0000FF; font-weight:bold;">return</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">include</span> A
  <span style="color:#9966CC; font-weight:bold;">include</span> B
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Creamos los modulos, la clase e incluimos los primeros en dicha clase.Hasta aqui nada nuevo bajo el sol.</p>
<p>Probemos entonces el codigo en irb,</p>

<div class="wp_syntax"><div class="code"><pre class="bash bash" style="font-family:monospace;">madtrick:~<span style="color: #000000; font-weight: bold;">/</span>programacion<span style="color: #000000; font-weight: bold;">/</span>ruby madtrick$ irb
irb<span style="color: #7a0874; font-weight: bold;">&#40;</span>main<span style="color: #7a0874; font-weight: bold;">&#41;</span>:001:0<span style="color: #000000; font-weight: bold;">&gt;</span> require <span style="color: #ff0000;">&quot;test30&quot;</span>
<span style="color: #ff0000;">&quot;Included module A&quot;</span>
<span style="color: #ff0000;">&quot;Included module B&quot;</span>
=<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #c20cb9; font-weight: bold;">true</span>
&nbsp;
irb<span style="color: #7a0874; font-weight: bold;">&#40;</span>main<span style="color: #7a0874; font-weight: bold;">&#41;</span>:002:0<span style="color: #000000; font-weight: bold;">&gt;</span> Test.new.test_method
<span style="color: #ff0000;">&quot;Doing something really important in module B&quot;</span>
<span style="color: #ff0000;">&quot;Doing something really important in module A&quot;</span>
<span style="color: #ff0000;">&quot;Inside method of class A&quot;</span>
&nbsp;
<span style="color: #ff0000;">&quot;Backtrace:&quot;</span>
<span style="color: #ff0000;">&quot;./test30.rb:14:in `test_method_B_without_filters'&quot;</span>
<span style="color: #ff0000;">&quot;./test30.rb:32:in `test_method'&quot;</span>
<span style="color: #ff0000;">&quot;(irb):2:in `irb_binding'&quot;</span>
<span style="color: #ff0000;">&quot;/opt/local/lib/ruby/1.8/irb/workspace.rb:52:in `irb_binding'&quot;</span>
<span style="color: #ff0000;">&quot;:0&quot;</span>
=<span style="color: #000000; font-weight: bold;">&gt;</span> nil</pre></div></div>

<p>Si hechamos un vistazo a la salida generada en irb,</p>

<div class="wp_syntax"><div class="code"><pre class="bash bash" style="font-family:monospace;">irb<span style="color: #7a0874; font-weight: bold;">&#40;</span>main<span style="color: #7a0874; font-weight: bold;">&#41;</span>:001:0<span style="color: #000000; font-weight: bold;">&gt;</span> require <span style="color: #ff0000;">&quot;test30&quot;</span>
<span style="color: #ff0000;">&quot;Included module A&quot;</span>
<span style="color: #ff0000;">&quot;Included module B&quot;</span>
=<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #c20cb9; font-weight: bold;">true</span></pre></div></div>

<p>Los modulos se incluyen en la clase en el orden deseado</p>

<div class="wp_syntax"><div class="code"><pre class="ruby ruby" style="font-family:monospace;">irb<span style="color:#006600; font-weight:bold;">&#40;</span>main<span style="color:#006600; font-weight:bold;">&#41;</span>:002:0<span style="color:#006600; font-weight:bold;">&gt;</span> <span style="color:#CC00FF; font-weight:bold;">Test</span>.<span style="color:#9900CC;">new</span>.<span style="color:#9900CC;">test_method</span>
<span style="color:#996600;">&quot;Doing something really important in module B&quot;</span>
<span style="color:#996600;">&quot;Doing something really important in module A&quot;</span>
<span style="color:#996600;">&quot;Inside method of class A&quot;</span></pre></div></div>

<p>Ahora creamos un objeto de tipo Test e invocamos sobre él el metodo &#8220;test_method&#8221;&#8230;!Pero que ha pasado aqui¡!De donde salen esa lineas¡No no pongamos nerviosos y averigüemos que pasa.</p>
<p>Cuando redefinimos el metodo <em>included</em> de la clase module, realizamos unos alias.<br />
Para el modulo A:</p>
<ul>
<li><strong>Nuevo nombre</strong> : test_method_A_without_filters,<strong>nombre antiguo</strong>: test_method</li>
<li><strong>Nuevo nombre</strong> : test_method, <strong>nombre_antiguo</strong> test_method_A_with_filters</li>
</ul>
<p>Para el modulo B , lo mismo pero cambiando la A por una B.</p>
<p>El resultado de estos alias es el que vemos en la salida de irb, al invocar sobre un objeto de la clase Test<br />
su metodo de instancia &#8220;test_method&#8221; lo primero que vemos no es &#8220;<em>Inside method of class A</em>&#8221; sino &#8220;<em>Doing something really important in module B</em>&#8220;,seguido de un &#8220;<em>Doing something really important in module A</em>&#8221; para finalmente ver nuestro esperado &#8220;<em>Inside method of class A</em>&#8220;,esto es asi porque:</p>
<ol>
<li>El ultimo modulo incluido fue el B, por tanto su alias &#8220;sobreescribioo&#8221; al creado por el modulo A.Es decir al hacer Test.new.test_method en realidad estamos invocando a test_method_B_with_filters</li>
<li>Tras ejecutar este metodo, invocamos al metodo &#8220;original&#8221;, que en este caso no es el definido en la clase, sino el alias realizado por el modulo A</li>
<li>Tras ejecutar este ultimo alias, volvemos a invocar al metodo original (alias de  &#8220;test_method_A_without_filters&#8221;) quien finalmente si que es el metodo de la clase Test</li>
</ol>
<p>Utilizando <a href="http://www.ruby-doc.org/core/classes/Kernel.html#M005955" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.ruby-doc.org');" target="_blank">caller</a> podemos saber la <a href="http://en.wikipedia.org/wiki/Stack_trace" onclick="javascript:pageTracker._trackPageview('/outbound/article/en.wikipedia.org');" target="_blank">stacktrace</a> de nuestro programa y asi saber cual fue la direccion de los mensajes.Esto lo podemos ver en este trozo de la salida de irb,</p>

<div class="wp_syntax"><div class="code"><pre class="bash bash" style="font-family:monospace;"><span style="color: #ff0000;">&quot;Backtrace:&quot;</span>
<span style="color: #ff0000;">&quot;./test30.rb:19:in `test_method_B_without_filters'&quot;</span>
<span style="color: #ff0000;">&quot;./test30.rb:30:in `test_method'&quot;</span>
<span style="color: #ff0000;">&quot;(irb):2:in `irb_binding'&quot;</span>
<span style="color: #ff0000;">&quot;/opt/local/lib/ruby/1.8/irb/workspace.rb:52:in `irb_binding'&quot;</span>
<span style="color: #ff0000;">&quot;:0&quot;</span></pre></div></div>

<p>Teniendo en cuenta que las primeras lineas indican los ultimos mensajes.Tenemos que:</p>
<p>En la linea 30 vamos enviar un mensaje tras recibir uno con destino a &#8220;<em>test_method</em>&#8221; alias de &#8220;<em>test_method_B_with_filters</em>&#8220;,</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>28
29
30
31
</pre></td><td class="code"><pre class="ruby ruby" style="font-family:monospace;">  <span style="color:#9966CC; font-weight:bold;">def</span> test_method_B_with_filters
    <span style="color:#CC0066; font-weight:bold;">p</span> <span style="color:#996600;">&quot;Doing something really important in module B&quot;</span>
    test_method_B_without_filters
  <span style="color:#9966CC; font-weight:bold;">end</span></pre></td></tr></table></div>

<p>En la linea 19 vamos a enviar un mensaje tras recibir uno con destino &#8220;<em>test_method_B_without_filters</em>&#8221;<br />
el cual es un alias de &#8220;<em>test_method</em>&#8220;,</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>17
18
19
20
</pre></td><td class="code"><pre class="ruby ruby" style="font-family:monospace;"> <span style="color:#9966CC; font-weight:bold;">def</span> test_method_A_with_filters
    <span style="color:#CC0066; font-weight:bold;">p</span> <span style="color:#996600;">&quot;Doing something really important in module A&quot;</span>
    test_method_A_without_filters
  <span style="color:#9966CC; font-weight:bold;">end</span></pre></td></tr></table></div>

<p>Como se puede apreciar es una forma bastante sencilla de añadir funcionalidad sin influir para nada en las clases.Y de aqui es de donde saque el titulo, porque literalmente estamos encadenando metodos.</p>
<p><strong>Para terminar</strong><br />
Si alguien le extraña la coletilla _filters que utilize para hacer los alias , tiene su explicacion.Ultimamente estoy curioseando en el codigo de <a href="http://www.rubyonrails.org/" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.rubyonrails.org');" target="_blank">Rails</a>, y para poder seguir un orden me voy guiando por el orden el que se procesan las peticiones ,gracias al debugger para webrick y otros servidores.Bueno la cosa es que llegue al fichero <a href="http://github.com/rails/rails/tree/master/actionpack/lib/action_controller/filters.rb" onclick="javascript:pageTracker._trackPageview('/outbound/article/github.com');">filters.rb</a>  donde me encontre con este codigo,</p>

<div class="wp_syntax"><div class="code"><pre class="ruby ruby" style="font-family:monospace;"> <span style="color:#9966CC; font-weight:bold;">module</span> InstanceMethods <span style="color:#008000; font-style:italic;"># :nodoc:</span>
      <span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">included</span><span style="color:#006600; font-weight:bold;">&#40;</span>base<span style="color:#006600; font-weight:bold;">&#41;</span>
        base.<span style="color:#9900CC;">class_eval</span> <span style="color:#9966CC; font-weight:bold;">do</span>
          alias_method_chain <span style="color:#ff3333; font-weight:bold;">:perform_action</span>, <span style="color:#ff3333; font-weight:bold;">:filters</span>
          alias_method_chain <span style="color:#ff3333; font-weight:bold;">:process</span>, <span style="color:#ff3333; font-weight:bold;">:filters</span>
        <span style="color:#9966CC; font-weight:bold;">end</span>
      <span style="color:#9966CC; font-weight:bold;">end</span>
...</pre></div></div>

<p>¿alias_method_chain?, no me sonaba para nada, asi que tras una consulta a google llegue a <a href="http://weblog.rubyonrails.org/2006/4/26/new-in-rails-module-alias_method_chain" onclick="javascript:pageTracker._trackPageview('/outbound/article/weblog.rubyonrails.org');">esto</a>:</p>
<blockquote><p>All over the internals of Rails you’ll find code like this in a module: </p>
<p>  module Layout #:nodoc:<br />
    def self.included(base)<br />
      base.extend(ClassMethods)<br />
      base.class_eval do<br />
        alias_method :render_with_no_layout, :render<br />
        alias_method :render, :render_with_a_layout<br />
        # &#8230; etc<br />
This makes it so that when the module is included into the base class, it adds behavior onto some method in that class without the method having to be aware of the fact that it’s being enhanced</p></blockquote>
<p>En resumidas cuentas, que <em>alias_method_chain</em> hace lo que acabos de hacer nosotros pero un poquillo mejor ya que se puede aplicar a cualquier metodo, no solo a <em>test_method</em> como en nuestro caso.</p>
<p>Volviendo a lo de la coletilla _filters, la explicacion es que donde vi el primer ejemplo de alias_method_chain fue en el codigo indicado arriba y entonces fue lo primero que se me ocurrio.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.tenako.com/2008/09/19/rubyrails-metodos-encadenados/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Ruby: metodos de clase privados</title>
		<link>http://blog.tenako.com/2008/09/18/ruby-metodos-de-clase-privados/</link>
		<comments>http://blog.tenako.com/2008/09/18/ruby-metodos-de-clase-privados/#comments</comments>
		<pubDate>Thu, 18 Sep 2008 15:57:15 +0000</pubDate>
		<dc:creator>farruco</dc:creator>
				<category><![CDATA[programacion]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[constantes]]></category>
		<category><![CDATA[dinamicas]]></category>

		<guid isPermaLink="false">http://blog.tenako.com/?p=3</guid>
		<description><![CDATA[Ayer aparecio una duda delante de mi y me asalto, ¿Metodos de clase privados?
La primera idea que me paso por la cabeza y que probe fue:

class Test
&#160;
private
def Test.class_method
p &#34;inside private class method&#34;
end
&#160;
end

Si pruebo este codigo en irb,

madtrick:~/programacion/ruby madtrick$ irb
irb&#40;main&#41;:001:0&#62; require &#34;test28&#34;
&#62; true
irb&#40;main&#41;:002:0&#62; Test.class_method
&#34;inside private class method&#34;
&#62; nil

Podemos ver que no, que esto no funciona porque [...]]]></description>
			<content:encoded><![CDATA[<p>Ayer aparecio una duda delante de mi y me asalto, ¿Metodos de clase privados?</p>
<p>La primera idea que me paso por la cabeza y que probe fue:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> <span style="color:#CC00FF; font-weight:bold;">Test</span>
&nbsp;
private
<span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#CC00FF; font-weight:bold;">Test</span>.<span style="color:#9900CC;">class_method</span>
<span style="color:#CC0066; font-weight:bold;">p</span> <span style="color:#996600;">&quot;inside private class method&quot;</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Si pruebo este codigo en irb,</p>

<div class="wp_syntax"><div class="code"><pre class="bash bash" style="font-family:monospace;">madtrick:~<span style="color: #000000; font-weight: bold;">/</span>programacion<span style="color: #000000; font-weight: bold;">/</span>ruby madtrick$ irb
irb<span style="color: #7a0874; font-weight: bold;">&#40;</span>main<span style="color: #7a0874; font-weight: bold;">&#41;</span>:001:0<span style="color: #000000; font-weight: bold;">&gt;</span> require <span style="color: #ff0000;">&quot;test28&quot;</span>
<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #c20cb9; font-weight: bold;">true</span>
irb<span style="color: #7a0874; font-weight: bold;">&#40;</span>main<span style="color: #7a0874; font-weight: bold;">&#41;</span>:002:0<span style="color: #000000; font-weight: bold;">&gt;</span> Test.class_method
<span style="color: #ff0000;">&quot;inside private class method&quot;</span>
<span style="color: #000000; font-weight: bold;">&gt;</span> nil</pre></div></div>

<p>Podemos ver que no, que esto no funciona porque me deja llamar al metodo perfectamente y todos sabemos que eso no puede pasar ya que en ruby los metodos privados solo permiten ser invocados con un &#8220;self&#8221; explicito.Realmente lo que acabo de decir no es del todo cierto, ya que los utilizando el metodo <em><a title="send" href="http://www.ruby-doc.org/core/classes/Object.html#M000334" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.ruby-doc.org');" target="_blank">send</a></em> para enviar el mensaje da igual la visibilidad del metodo que lo reciva.</p>
<p>Lo que no entiendo es porque falla, supongo que sera porque la restriccion de visibilidad que implica <em>private</em> solo afectara a los metodos de instancia de la clase.Si alguien quiere aportar mas luz sobre esto&#8230;</p>
<p>Volviendo al tema, probemos con el metodo private_class_method.Este metodo cambia la visibilidad de cualquier metodo a privada.Veamos un ejemplo:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> <span style="color:#CC00FF; font-weight:bold;">Test</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#CC00FF; font-weight:bold;">Test</span>.<span style="color:#9900CC;">class_method</span>
<span style="color:#CC0066; font-weight:bold;">p</span> <span style="color:#996600;">&quot;inside private class method&quot;</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
private_class_method <span style="color:#ff3333; font-weight:bold;">:class_method</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Lo probamos,</p>

<div class="wp_syntax"><div class="code"><pre class="bash bash" style="font-family:monospace;">madtrick:~<span style="color: #000000; font-weight: bold;">/</span>programacion<span style="color: #000000; font-weight: bold;">/</span>ruby madtrick$ irb
irb<span style="color: #7a0874; font-weight: bold;">&#40;</span>main<span style="color: #7a0874; font-weight: bold;">&#41;</span>:001:0<span style="color: #000000; font-weight: bold;">&gt;</span> require <span style="color: #ff0000;">&quot;test28&quot;</span>
<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #c20cb9; font-weight: bold;">true</span>
irb<span style="color: #7a0874; font-weight: bold;">&#40;</span>main<span style="color: #7a0874; font-weight: bold;">&#41;</span>:002:0<span style="color: #000000; font-weight: bold;">&gt;</span> Test.class_method
NoMethodError: private method <span style="color: #000000; font-weight: bold;">`</span>class_method<span style="color: #ff0000;">' called for Test:Class
from (irb):2</span></pre></div></div>

<p>Esto ya es otra cosa,es lo esperado.Este metodo esta muy bien ya que permite cambiar la visibilidad a que por ejemplo herede nuestra clase.</p>
<p>Pero aun nos queda una manera mas de definidir metodos de clase que sean privados.</p>
<p>Como en ruby todo es un objeto, las señoras clases tambien son objetos (de la clase Class).Por tanto tambien pueden tener metodos de instancia, que a efectos practicos se comportan como los metodos de clase definidos de forma normal y corriente en una clase.</p>
<p>¿Y como añado yo metodos de instancia a una clase?Pues hay varios metodos pero el mas sencillo (o por lo menos eso me parece  a mi -se aceptan sugerencias) es el siguiente:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> <span style="color:#CC00FF; font-weight:bold;">Test</span>
    <span style="color:#9966CC; font-weight:bold;">class</span> <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> <span style="color:#0000FF; font-weight:bold;">self</span>
      private
        <span style="color:#9966CC; font-weight:bold;">def</span> class_method
         <span style="color:#CC0066; font-weight:bold;">p</span> <span style="color:#996600;">&quot;inside private class method&quot;</span>
        <span style="color:#9966CC; font-weight:bold;">end</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Lo que acabamos de hacer es abrir la metaclase o clase-virtual de la clase para añadir un el metodo class_method con visibilidad privada.Para el que no sepa que son las clases virtuales o metaclases, le recomiendo leer los enlaces que menciono al final del post.</p>
<p>Si ejecutamos esto en irb,</p>

<div class="wp_syntax"><div class="code"><pre class="bash bash" style="font-family:monospace;">madtrick:~<span style="color: #000000; font-weight: bold;">/</span>programacion<span style="color: #000000; font-weight: bold;">/</span>ruby madtrick$ irb
irb<span style="color: #7a0874; font-weight: bold;">&#40;</span>main<span style="color: #7a0874; font-weight: bold;">&#41;</span>:001:0<span style="color: #000000; font-weight: bold;">&gt;</span> require <span style="color: #ff0000;">&quot;test28&quot;</span>
<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #c20cb9; font-weight: bold;">true</span>
irb<span style="color: #7a0874; font-weight: bold;">&#40;</span>main<span style="color: #7a0874; font-weight: bold;">&#41;</span>:002:0<span style="color: #000000; font-weight: bold;">&gt;</span> Test.class_method
NoMethodError: private method <span style="color: #000000; font-weight: bold;">`</span>class_method<span style="color: #ff0000;">' called for Test:Class
from (irb):2</span></pre></div></div>

<p>Una vez mas, funciona correctamente.</p>
<p>Si quieres saber algo mas sobre las metaclasses o clases-virtuales te recomiendo que le heches un vistazo a:</p>
<p><a href="http://whytheluckystiff.net/articles/seeingMetaclassesClearly.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/whytheluckystiff.net');" target="_blank"><em>Seein metaclasses clearly</em></a></p>
<p><a href="http://www.ruby-forum.com/topic/102986" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.ruby-forum.com');" target="_blank"><em>Why virtual classes? </em></a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.tenako.com/2008/09/18/ruby-metodos-de-clase-privados/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
