<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://msmvps.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Angel "Java" Lopez : Rails</title><link>http://msmvps.com/blogs/lopez/archive/tags/Rails/default.aspx</link><description>Tags: Rails</description><dc:language>en</dc:language><generator>CommunityServer 2008.5 SP2 (Build: 40407.4157)</generator><item><title>Esos Raros Lenguajes Nuevos (1) VANs en ALT.NET Hispano</title><link>http://msmvps.com/blogs/lopez/archive/2012/04/09/esos-raros-lenguajes-nuevos-1-vans-en-alt-net-hispano.aspx</link><pubDate>Mon, 09 Apr 2012 17:33:42 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1808672</guid><dc:creator>lopez</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1808672</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2012/04/09/esos-raros-lenguajes-nuevos-1-vans-en-alt-net-hispano.aspx#comments</comments><description>&lt;p&gt;En Marzo dí una charla presencial en el Microsoft User Group de Argentina, en Buenos Aires, ver:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2012/03/03/esos-raros-lenguajes-nuevos-javascript-node-scala-erlang-clojure-ruby-python.aspx" target="_blank"&gt;Esos Raros Lenguajes Nuevos: Javascript/Node, Scala, Erlang, Clojure, Ruby, Python&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Ahora, el sábado que viene (14 de Abril) y el siguiente sábado (21 de Abril) la gente de ALT.NET Hispano ha organizado dos VAN (reuniones virtuales) para que pueda comentar sobre esos lenguajes, que no son tan raros ni tan nuevos, pero que en general pueden parecerlo dentro de la comunidad .NET:&lt;/p&gt;  &lt;p&gt;- Javascript en NodeJs   &lt;br /&gt;- Scala    &lt;br /&gt;- Erlang    &lt;br /&gt;- Clojure    &lt;br /&gt;- Python    &lt;br /&gt;- Ruby&lt;/p&gt;  &lt;p&gt;Este es el anuncio de la primera reunión:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;La comunidad &lt;a href="http://www.google.com/url?q=http%3A%2F%2FALT.NET&amp;amp;usd=2&amp;amp;usg=AFQjCNHCjdfpizsVyIZTzgBVm4uK2byWhg"&gt;ALT.NET&lt;/a&gt; Hispano (&lt;a href="http://www.google.com/url?q=http%3A%2F%2Faltnethispano.org&amp;amp;usd=2&amp;amp;usg=AFQjCNH7X-EhZD5RMHGyIk-0o4VZaQM7Xg"&gt;http://altnethispano.org&lt;/a&gt;) realizará una VAN sobre Esos raros lenguajes nuevos NodeJs, Scala, Clojure, Erlang, Python, Ruby Parte 1, con Angel Java Lopez.&lt;/p&gt;    &lt;p&gt;Fecha: Sábado 14 de Abril del 2012 a las 18:00 hrs. Hora Internacional (GMT/UTC), con una duración aproximada de 2 horas.&lt;/p&gt;    &lt;p&gt;Pueden plantear sus comentarios e inquietudes sobre el tema de la reunión en: &lt;a href="https://groups.google.com/d/topic/altnet-hispano/mRQRHvoAvKc/discussion"&gt;https://groups.google.com/d/topic/altnet-hispano/mRQRHvoAvKc/discussion&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;Para mayor información sobre cómo atender la reunión consulten: &lt;a href="http://tinyurl.com/van-hispano"&gt;http://tinyurl.com/van-hispano&lt;/a&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Mi idea es mostrar a qué problemas se orientan estos lenguajes. Por ejemplo, cómo tratan de resolver temas de escalabilidad y computación distribuida en los cuatro primeros (Javascript en NodeJs, Scala, Erlang, Clojure). Y cómo se ha ido formando comunidades, y ecosistemas de paquetes y desarrollo web, especialmente en los dos últimos (Python y Ruby). Mi plan es dar los tres primeros (Javascript/NodeJs, Scala, Erlang) este sábado que viene, y los otros (Clojure, Python, Ruby) en la siguiente sesión.&lt;/p&gt;  &lt;p&gt;Este es el primer post de la serie, donde voy a ir escribiendo, comentando sobre recursos y enlaces que fui descubriendo, además de los ya presentados en el post que mencioné al principio.&lt;/p&gt;  &lt;p&gt;Nos leemos!&lt;/p&gt;  &lt;p&gt;Angel &amp;quot;Java&amp;quot; Lopez   &lt;br /&gt;&lt;a href="http://www.ajlopez.com"&gt;http://www.ajlopez.com&lt;/a&gt;    &lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1808672" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/Lenguajes+de+Programaci_26002300_243_3B00_n/default.aspx">Lenguajes de Programaci&amp;#243;n</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Scala/default.aspx">Scala</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Python/default.aspx">Python</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Javascript/default.aspx">Javascript</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/NodeJs/default.aspx">NodeJs</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Ruby/default.aspx">Ruby</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Rails/default.aspx">Rails</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Erlang/default.aspx">Erlang</category></item><item><title>Esos Raros Lenguajes Nuevos: Javascript/Node, Scala, Erlang, Clojure, Ruby, Python</title><link>http://msmvps.com/blogs/lopez/archive/2012/03/03/esos-raros-lenguajes-nuevos-javascript-node-scala-erlang-clojure-ruby-python.aspx</link><pubDate>Sat, 03 Mar 2012 18:21:37 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1806851</guid><dc:creator>lopez</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1806851</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2012/03/03/esos-raros-lenguajes-nuevos-javascript-node-scala-erlang-clojure-ruby-python.aspx#comments</comments><description>&lt;p&gt;El jueves pasado tuve el gusto de dar una charla sobre lenguajes, en el &lt;a href="http://www.mug.org.ar"&gt;Microsoft User Group de Argentina&lt;/a&gt;, en su sede de Buenos Aires. Mi idea era presentar lenguajes de programación, alguno nuevo, otros ya con más de 15 años de existencia, que la comunidad de programadores .NET o de tecnologías Microsoft no ve frecuentemente.&lt;/p&gt;  &lt;p&gt;Para mí, es un tema interesante: ver que a lo largo del tiempo, en la historia de la computación, hay lenguajes de programación que aparecen, tiene éxito u olvido. Pasan los años, y seguimos teniendo nuevos lenguajes. Vean que en el ambiente de las computadoras personales, no ha pasado lo mismo con los sistemas operativos: prácticamente se estabilizó en dos opciones con variantes: Windows y Linux (y otros Unix no derivados de Linux directamente). Podría poner Mac OS como aparte también. En cambio, en el ámbito de los lenguajes de programación, sigue habiendo actividad de creación, y viejos lenguajes aún sobreviven (desde Fortran hasta COBOL, y Smalltalk, por poner ejemplos diversos). Y aparecen lenguajes nuevos cada año, como en el 2011 que vió nacer a Dart, de la mano de Google (que también se animó antes a crear el lenguaje Go).&lt;/p&gt;  &lt;p&gt;Los lenguajes que presenté fueron:   &lt;br /&gt;- Javascript (en NodeJs)    &lt;br /&gt;- Scala    &lt;br /&gt;- Erlang    &lt;br /&gt;- Clojure    &lt;br /&gt;- Ruby    &lt;br /&gt;- Python (no alcanzó el tiempo, pero lo incluyo en este post) &lt;/p&gt;  &lt;p&gt;Un punto que destaqué es que los primeros cuatro (Javascript/NodeJs, Scala, Clojure, Erlang) tratan, entre otros objetivos, de encarar el problema de paralelismo, y multithreading. Ante la desaceleración de la ley de Moore, se trata de aprovechar el hardware de computadoras multicore. Eso lleva a que los lenguajes tengan que soportar múltiples threads (tema que casi todos hoy soportan, de una u otra forma, aunque algunos sólo recientemente: Smalltak, Ruby tuvieron mucho tiempo implementados “green threads”, hilos simulados por el lenguaje, sin aprovechar los threads del sistema operativo, que explotan los múltiples recursos del hardware). Pero también lleva a la complicación: tenemos que escribir programas contenplando múltitples hilos de ejecución, concurrencia, condiciones de carrera, lockeos, etc. Veremos que Erlang (y Scala con Akka) lleva a un paso más: ejecutar en varias máquinas. Ese camino es muy interesante para mí, porque libera la restricción de tener que explotar solamente una máquina: para procesos pesados (desde web crawling, big data, etc...) podemos repartir el trabajo en varias máquinas “normales”. De hecho, vean cómo el mercado de las supercomputadoras ha ido decayendo, porque desde fines del siglo pasado se han encontrado soluciones basadas en clusters, grillas, etc... con varias computadoras atacando un problema. &lt;/p&gt;  &lt;p&gt;También quería mostrar que estos lenguajes se pueden probar en Windows, sin grandes problemas de instalación. Muchos de estos lenguajes “nuevos y raros” nacen en ambientes Unix/Linux y no siempre su instalación en Windows fue fácil. Pero en estos tiempos, ya tenemos un buen soporte de Windows para los lenguajes que presenté. &lt;/p&gt;  &lt;p&gt;De cada lenguaje mostré algún ejemplo simple, y otro ejemplo más complejo (aunque corto) que mostrara alguna característica destacada.&amp;#160; Espero poder volcar todos los enlaces y comentarios hechos en este post. Comencemos. &lt;/p&gt;  &lt;h3&gt;Javascript/NodeJs &lt;/h3&gt;  &lt;p&gt;Sitio: &lt;a href="http://nodejs.org/"&gt;http://nodejs.org/&lt;/a&gt;    &lt;br /&gt;Descripción, Historia: &lt;a href="http://en.wikipedia.org/wiki/Nodejs"&gt;http://en.wikipedia.org/wiki/Nodejs&lt;/a&gt; &lt;a href="http://en.wikipedia.org/wiki/JavaScript"&gt;http://en.wikipedia.org/wiki/JavaScript&lt;/a&gt;    &lt;br /&gt;Download que usé: el de Windows v0.6.7 pero pueden usar cualquiera de Windows 6.x. La actual es &lt;a href="http://nodejs.org/dist/v0.6.12/node-v0.6.12.msi"&gt;http://nodejs.org/dist/v0.6.12/node-v0.6.12.msi&lt;/a&gt;    &lt;br /&gt;Listas de Correo: &lt;a href="http://groups.google.com/group/nodejs"&gt;http://groups.google.com/group/nodejs&lt;/a&gt; &lt;a href="http://groups.google.com/group/nodejs-dev"&gt;http://groups.google.com/group/nodejs-dev&lt;/a&gt;    &lt;br /&gt;Ejemplos que usé: &lt;a href="https://github.com/ajlopez/NodeSamples"&gt;https://github.com/ajlopez/NodeSamples&lt;/a&gt;    &lt;br /&gt;Mostré un servidor HTTP simplícimo, hello world asincrónico, y dibujar en canvas multiusuario, usando el módulo socket.io    &lt;br /&gt;Mis enlaces: &lt;a href="http://delicious.com/ajlopez/nodejs"&gt;http://delicious.com/ajlopez/nodejs&lt;/a&gt;    &lt;br /&gt;Mis posts: &lt;a href="http://ajlopez.wordpress.com/category/nodejs/"&gt;http://ajlopez.wordpress.com/category/nodejs/&lt;/a&gt; &lt;a href="http://msmvps.com/blogs/lopez/archive/tags/NodeJs/default.aspx"&gt;http://msmvps.com/blogs/lopez/archive/tags/NodeJs/default.aspx&lt;/a&gt;    &lt;br /&gt;En especial:    &lt;br /&gt;Programando Juegos Sociales en Línea (Parte 8) Agregando Node.js    &lt;br /&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2012/01/12/social_2D00_games_2D00_programming_2D00_part_2D00_8_2D00_adding_2D00_node_2D00_js.aspx"&gt;http://msmvps.com/blogs/lopez/archive/2012/01/12/social_2D00_games_2D00_programming_2D00_part_2D00_8_2D00_adding_2D00_node_2D00_js.aspx&lt;/a&gt;    &lt;br /&gt;AjFabriq en NodeJs (Parte 3) Una aplicación Distribuida Simple    &lt;br /&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2011/09/15/ajfabriq_2D00_on_2D00_nodejs_2D00_part_2D00_3_2D00_a_2D00_distributed_2D00_simple_2D00_application.aspx"&gt;http://msmvps.com/blogs/lopez/archive/2011/09/15/ajfabriq_2D00_on_2D00_nodejs_2D00_part_2D00_3_2D00_a_2D00_distributed_2D00_simple_2D00_application.aspx&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Javascript aparece como lenguaje en el lanzamiento del Netscape Navigator de 1995 (éramos tan pobres :-). Fue desarrollado por Brendan Eich &lt;a href="http://en.wikipedia.org/wiki/Brendan_Eich"&gt;http://en.wikipedia.org/wiki/Brendan_Eich&lt;/a&gt; de Netscape, con el nombre Mocha (un gusto de café como también lo es la palabra “java”) y luego LiveScript.    &lt;br /&gt;Node.js es creado por Ryah Dahl de Joyent &lt;a href="http://joyent.com/"&gt;http://joyent.com/&lt;/a&gt; Pueden ver un video de introducción en &lt;a href="http://ajlopez.wordpress.com/2011/10/15/code-snippets-are-for-sissies/"&gt;http://ajlopez.wordpress.com/2011/10/15/code-snippets-are-for-sissies/&lt;/a&gt;    &lt;br /&gt;&lt;/p&gt;  &lt;p&gt;Comentarios:   &lt;br /&gt;&lt;/p&gt;  &lt;p&gt;Node.js tiene un REPL (Read Eval Print Loop)    &lt;br /&gt;Corre sobre el motor de Javascript Google V8. Un motor muy rápido, pero orientado a tener un solo thread a nivel de Javascript (en las librerías internas de C usa threads). Node.js entonces implementa servidores (y código general, si uno quiere) que ejecutan un solo thread de Javascript. Con eso evita el problema de programar en múltiples threads. Pero entonces ¿qué ganamos? Todo Node.js (sus funciones de base, los módulos adicionales) se orienta a ejecución asincrónica. Por ejemplo, el thread principal puede pedir una consulta a una base de datos (usando un driver/módulo de Node.Js adecuado) SIN QUEDARSE esperando la respuesta. El thread principal sigue ejecutando. Cuando la consulta de base de datos tiene algún resultado, lo anuncia (en un sistema interno de eventos). El thread principal de Javascript está atendiendo esos eventos. La escalabilidad se logra aprovechando que la entrada/salida (a disco, red, etc.) se puede derivar asincrónicamente, sin ocupar el thread principal. Internamente, usa características de los sistemas operativos (como el soporte de select() en Linux, o los Completion I/O ports de Windows).    &lt;br /&gt;En el ejemplo de dibujo sobre canvas usando socket.io, usamos npm para instalar el módulo:&lt;/p&gt;  &lt;p&gt;&lt;font size="4" face="Consolas"&gt;npm install socket.io&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;desde el directorio Server &lt;/p&gt;  &lt;h3&gt;Scala &lt;/h3&gt;  &lt;p&gt;Sitio: &lt;a href="http://www.scala-lang.org/"&gt;http://www.scala-lang.org/&lt;/a&gt;    &lt;br /&gt;Descripción e Historia: &lt;a href="http://en.wikipedia.org/wiki/Scala_(programming_language)"&gt;http://en.wikipedia.org/wiki/Scala_(programming_language)&lt;/a&gt;    &lt;br /&gt;Download: &lt;a href="http://www.scala-lang.org/downloads"&gt;http://www.scala-lang.org/downloads&lt;/a&gt; yo usé &lt;a href="http://www.scala-lang.org/downloads/distrib/files/scala-2.9.1.final.zip"&gt;http://www.scala-lang.org/downloads/distrib/files/scala-2.9.1.final.zip&lt;/a&gt; lo expandi y agregué el directorio bin al PATH    &lt;br /&gt;Ejemplos: &lt;a href="https://github.com/ajlopez/ProgrammingLanguagesSamples/tree/master/Scala"&gt;https://github.com/ajlopez/ProgrammingLanguagesSamples/tree/master/Scala&lt;/a&gt; Ver los ejemplos de &lt;a href="http://www.scala-lang.org/node/219"&gt;http://www.scala-lang.org/node/219&lt;/a&gt;    &lt;br /&gt;Hola mundo en: &lt;a href="http://www.scala-lang.org/node/166"&gt;http://www.scala-lang.org/node/166&lt;/a&gt;    &lt;br /&gt;Ejemplos avanzados: &lt;a href="http://www.scala-lang.org/node/44"&gt;http://www.scala-lang.org/node/44&lt;/a&gt;    &lt;br /&gt;Actores: &lt;a href="http://www.scala-lang.org/node/242"&gt;http://www.scala-lang.org/node/242&lt;/a&gt;    &lt;br /&gt;El ejemplo ping pong: &lt;a href="http://www.scala-lang.org/node/54"&gt;http://www.scala-lang.org/node/54&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Lo ejecutamos con&lt;/p&gt;  &lt;p&gt;&lt;font size="4" face="Consolas"&gt;scalac pingpong.scala     &lt;br /&gt;scala -cp . examples.actors.pingpong&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;Ejemplo de mensajes entre actores: &lt;a href="http://www.scala-lang.org/node/50"&gt;http://www.scala-lang.org/node/50&lt;/a&gt;    &lt;br /&gt;Mis enlaces: &lt;a href="http://www.delicious.com/ajlopez/scala"&gt;http://www.delicious.com/ajlopez/scala&lt;/a&gt;    &lt;br /&gt;Mis posts: &lt;a href="http://ajlopez.wordpress.com/category/scala/"&gt;http://ajlopez.wordpress.com/category/scala/&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Comentarios:&lt;/p&gt;  &lt;p&gt;Es multiparadigma (soporta objetos/clases y programación funcional). Lenguaje de autor, creado principalmente por Martin Odersky &lt;a href="http://en.wikipedia.org/wiki/Martin_Odersky"&gt;http://en.wikipedia.org/wiki/Martin_Odersky&lt;/a&gt; Compila a Java y permite reducir la ceremonia (por ejemplo, soporte de declarar directamente un objeto único, sin necesidad de declarar clase). Soporta actores, ejemplo que mostré en la charla. Con actores, Scala evita que el programador tenga que encargarse de los lockeos y manejo de múltiples threads.    &lt;br /&gt;Sobre actores ver: &lt;a href="http://delicious.com/ajlopez/actormodel"&gt;http://delicious.com/ajlopez/actormodel&lt;/a&gt; &lt;a href="http://en.wikipedia.org/wiki/Actor_model"&gt;http://en.wikipedia.org/wiki/Actor_model&lt;/a&gt;    &lt;br /&gt;y también message passing: &lt;a href="http://en.wikipedia.org/wiki/Message_passing"&gt;http://en.wikipedia.org/wiki/Message_passing&lt;/a&gt;    &lt;br /&gt;Ver el proyecto Akka, que extiende Scala a actores distribuidos: &lt;a href="http://akka.io/"&gt;http://akka.io/&lt;/a&gt;&lt;/p&gt;  &lt;h3&gt;Clojure&lt;/h3&gt;  &lt;p&gt;   &lt;br /&gt;Sitio: &lt;a href="http://clojure.org/"&gt;http://clojure.org/&lt;/a&gt;    &lt;br /&gt;Descripción e Historia: &lt;a href="http://en.wikipedia.org/wiki/Clojure"&gt;http://en.wikipedia.org/wiki/Clojure&lt;/a&gt;    &lt;br /&gt;Download: Ver &lt;a href="http://clojure.org/downloads"&gt;http://clojure.org/downloads&lt;/a&gt; Yo usé &lt;a href="http://repo1.maven.org/maven2/org/clojure/clojure/1.3.0/clojure-1.3.0.zip"&gt;http://repo1.maven.org/maven2/org/clojure/clojure/1.3.0/clojure-1.3.0.zip&lt;/a&gt; y también la versión 1.2.0    &lt;br /&gt;Listas de Correo: &lt;a href="http://groups.google.com/group/clojure"&gt;http://groups.google.com/group/clojure&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Comentarios:&lt;/p&gt;  &lt;p&gt;Vimos cómo Clojure es un dialecto de Lisp, y tiene homoniconicity &lt;a href="http://en.wikipedia.org/wiki/Homoiconicity"&gt;http://en.wikipedia.org/wiki/Homoiconicity&lt;/a&gt; . Compila internamente a Java, y hay una versión para CLR (Common Language Runtime de .NET). Mostré en el ejemplo de Game of Life &lt;a href="http://www.youtube.com/watch?v=CFCYVfApPUc"&gt;http://www.youtube.com/watch?v=CFCYVfApPUc&lt;/a&gt; &lt;a href="http://github.com/sfraser/MultithreadedGameOfLife"&gt;http://github.com/sfraser/MultithreadedGameOfLife&lt;/a&gt; el uso de Software Transactional Memory, ver &lt;a href="http://en.wikipedia.org/wiki/Software_transactional_memory"&gt;http://en.wikipedia.org/wiki/Software_transactional_memory&lt;/a&gt; que es una de las formas que tiene Clojure de “atacar” el problema de la concurrencia.    &lt;br /&gt;Para probar Clojure en línea ver &lt;a href="http://tryclj.com/"&gt;http://tryclj.com/&lt;/a&gt;    &lt;br /&gt;Ver &lt;a href="http://java.ociweb.com/mark/stm/article.html"&gt;http://java.ociweb.com/mark/stm/article.html&lt;/a&gt; sobre STM &lt;/p&gt;  &lt;h3&gt;Erlang &lt;/h3&gt;  &lt;p&gt;Sitio: &lt;a href="http://www.erlang.org/"&gt;http://www.erlang.org/&lt;/a&gt;    &lt;br /&gt;Descripción e Historia: &lt;a href="http://en.wikipedia.org/wiki/Erlang_(programming_language)"&gt;http://en.wikipedia.org/wiki/Erlang_(programming_language)&lt;/a&gt;    &lt;br /&gt;Download: &lt;a href="http://www.erlang.org/download.html"&gt;http://www.erlang.org/download.html&lt;/a&gt; Yo usé &lt;a href="http://www.erlang.org/download/otp_win32_R15B.exe"&gt;http://www.erlang.org/download/otp_win32_R15B.exe&lt;/a&gt;    &lt;br /&gt;Ejemplos: &lt;a href="http://pragprog.com/titles/jaerlang/source_code"&gt;http://pragprog.com/titles/jaerlang/source_code&lt;/a&gt; del libro de Joe Armstrong Programming Erlang &lt;a href="http://pragprog.com/book/jaerlang/programming-erlang"&gt;http://pragprog.com/book/jaerlang/programming-erlang&lt;/a&gt; Ejemplos más sencillos: &lt;a href="https://github.com/ajlopez/ProgrammingLanguagesSamples/tree/master/Erlang"&gt;https://github.com/ajlopez/ProgrammingLanguagesSamples/tree/master/Erlang&lt;/a&gt; a ir actualizando.    &lt;br /&gt;Primeros pasos: &lt;a href="http://www.erlang.org/static/getting_started_quickly.html"&gt;http://www.erlang.org/static/getting_started_quickly.html&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Comunidad en Argentina: &lt;a href="http://erlang.org.ar/"&gt;http://erlang.org.ar/&lt;/a&gt;    &lt;br /&gt;Lista de Correo de Argentina: &lt;a href="http://erlang.org.ar/ListaDeCorreo"&gt;http://erlang.org.ar/ListaDeCorreo&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Comentarios:&lt;/p&gt;  &lt;p&gt;Vimos que Erlang es un lenguaje funcional: no hay variables, una vez ligada una “variable” a un valor, no se puede modificar. Todas son funciones. Tenemos varios procesos. Vimos el ejemplo key value store (kvs.erl) del libro de Joe Armsgrong. &lt;/p&gt;  &lt;p&gt;Ejecutamos en el REPL erl: &lt;/p&gt;  &lt;p&gt;&lt;font size="3" face="Consolas"&gt;c(kvs).     &lt;br /&gt;kvs:start().      &lt;br /&gt;kvs:store(apple, 10).      &lt;br /&gt;kvs:lookup(apple). &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;Luego vimos de lanzar DOS cajas de DOS. En una:&lt;/p&gt;  &lt;p&gt;&lt;font size="3" face="Consolas"&gt;erl -sname galdalf     &lt;br /&gt;c(kvs).      &lt;br /&gt;kvs:start(). &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;en la otra ejecutamos:&lt;/p&gt;  &lt;p&gt;&lt;font size="3" face="Consolas"&gt;erl -sname bilbo     &lt;br /&gt;rpc:call(gandalf@localhost, kvs, store, [apple, 10]).      &lt;br /&gt;rpc:call(gandalf@localhost, kvs, lookup, [apple]). &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;Caso de éxito &lt;a href="http://couchdb.apache.org/"&gt;http://couchdb.apache.org/&lt;/a&gt;&amp;#160; NoSQL reescrito en Erlang. &lt;/p&gt;  &lt;p&gt;Post &lt;a href="http://ajlopez.wordpress.com/2011/08/24/erlang-links-news-and-resources-1/"&gt;http://ajlopez.wordpress.com/2011/08/24/erlang-links-news-and-resources-1/&lt;/a&gt;    &lt;br /&gt;Mis enlaces: &lt;a href="http://delicious.com/ajlopez/erlang"&gt;http://delicious.com/ajlopez/erlang&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lambda-the-ultimate.org/node/4453"&gt;http://lambda-the-ultimate.org/node/4453&lt;/a&gt; Long rant on Erlang-style Actors: Lost Dimension &lt;/p&gt;  &lt;p&gt;Vean el lenguaje E:   &lt;br /&gt;&lt;a href="http://erights.org/index.html"&gt;http://erights.org/index.html&lt;/a&gt;    &lt;br /&gt;&lt;a href="http://wiki.erights.org/wiki/Walnut"&gt;http://wiki.erights.org/wiki/Walnut&lt;/a&gt;    &lt;br /&gt;&lt;a href="http://erights.org/talks/thesis/index.html"&gt;http://erights.org/talks/thesis/index.html&lt;/a&gt;&lt;/p&gt;  &lt;h3&gt;Ruby &lt;/h3&gt;  &lt;p&gt;Sitio: &lt;a href="http://www.ruby-lang.org/en/"&gt;http://www.ruby-lang.org/en/&lt;/a&gt;    &lt;br /&gt;Descripción e Historia: &lt;a href="http://en.wikipedia.org/wiki/Ruby_(programming_language)"&gt;http://en.wikipedia.org/wiki/Ruby_(programming_language)&lt;/a&gt;    &lt;br /&gt;Download: &lt;a href="http://www.ruby-lang.org/en/downloads/"&gt;http://www.ruby-lang.org/en/downloads/&lt;/a&gt; Yo usé &lt;a href="http://rubyinstaller.org/downloads/"&gt;http://rubyinstaller.org/downloads/&lt;/a&gt; Revisar mis posts sobre detalles de instalación importantes, como el DevKit. Y tambien &lt;a href="http://delicious.com/ajlopez/ruby+install"&gt;http://delicious.com/ajlopez/ruby+install&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Mis posts: &lt;a href="http://ajlopez.wordpress.com/category/ruby"&gt;http://ajlopez.wordpress.com/category/ruby&lt;/a&gt; &lt;a href="http://msmvps.com/blogs/lopez/archive/tags/ruby/default.aspx"&gt;http://msmvps.com/blogs/lopez/archive/tags/ruby/default.aspx&lt;/a&gt; donde explico paso a paso instalación de Ruby, Rails, y un primer sitio Rails. Y también mi experiencia en el último Ruby Meetup de Buenos Aires.    &lt;br /&gt;Mis enlaces: &lt;a href="http://delicious.com/ajlopez/ruby"&gt;http://delicious.com/ajlopez/ruby&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Comunidad en Argentina: &lt;a href="http://ruby.com.ar/"&gt;http://ruby.com.ar/&lt;/a&gt;    &lt;br /&gt;Conferencia 2011: &lt;a href="http://rubyconfargentina.org/en"&gt;http://rubyconfargentina.org/en&lt;/a&gt;    &lt;br /&gt;Lista de Correo Argentina, Latinoamérica: &lt;a href="http://groups.google.com/group/rubysur"&gt;http://groups.google.com/group/rubysur&lt;/a&gt;    &lt;br /&gt;Sitio: &lt;a href="http://rubysur.org/"&gt;http://rubysur.org/&lt;/a&gt;&lt;/p&gt;  &lt;h3&gt;Python &lt;/h3&gt;  &lt;p&gt;Sitio: &lt;a href="http://python.org/"&gt;http://python.org/&lt;/a&gt;    &lt;br /&gt;Descripción e Historia: &lt;a href="http://en.wikipedia.org/wiki/Python_(programming_language)"&gt;http://en.wikipedia.org/wiki/Python_(programming_language)&lt;/a&gt;    &lt;br /&gt;Download: Hay dos versiones, usé &lt;a href="http://python.org/ftp/python/2.7.2/python-2.7.2.msi"&gt;http://python.org/ftp/python/2.7.2/python-2.7.2.msi&lt;/a&gt; y también tenía instalado &lt;a href="http://python.org/ftp/python/3.2.2/python-3.2.2.msi"&gt;http://python.org/ftp/python/3.2.2/python-3.2.2.msi&lt;/a&gt; Pero sólo la última instalación está ligada a ejecutar automáticamente los archivos .py, ver &lt;a href="http://stackoverflow.com/questions/3809314/how-to-install-both-python-2-x-and-python-3-x-in-windows-7"&gt;http://stackoverflow.com/questions/3809314/how-to-install-both-python-2-x-and-python-3-x-in-windows-7&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Ejemplos simples: &lt;a href="https://github.com/ajlopez/ProgrammingLanguagesSamples/tree/master/Python"&gt;https://github.com/ajlopez/ProgrammingLanguagesSamples/tree/master/Python&lt;/a&gt;    &lt;br /&gt;Comunidad en Argentina: &lt;a href="http://python.org.ar/pyar/"&gt;http://python.org.ar/pyar/&lt;/a&gt;    &lt;br /&gt;Lista de Correo en Argentina: &lt;a href="http://listas.python.org.ar/listinfo/pyar"&gt;http://listas.python.org.ar/listinfo/pyar&lt;/a&gt;    &lt;br /&gt;Vean el video anunciando la próxima PyCon &lt;a href="http://animoto.com/play/zVp1IGeGaLVKco0FDlwcmA"&gt;http://animoto.com/play/zVp1IGeGaLVKco0FDlwcmA&lt;/a&gt;    &lt;br /&gt;Mostré Django     &lt;br /&gt;&lt;a href="https://www.djangoproject.com/"&gt;https://www.djangoproject.com/&lt;/a&gt;    &lt;br /&gt;&lt;a href="https://docs.djangoproject.com/en/1.3/topics/install/#installing-official-release"&gt;https://docs.djangoproject.com/en/1.3/topics/install/#installing-official-release&lt;/a&gt;    &lt;br /&gt;C:\Software\Django-1.3.1    &lt;br /&gt;&lt;a href="https://docs.djangoproject.com/en/1.3/intro/tutorial01/"&gt;https://docs.djangoproject.com/en/1.3/intro/tutorial01/&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Ver también   &lt;br /&gt;&lt;a href="http://ironpython.codeplex.com/"&gt;IronPython&lt;/a&gt; (Python running on .NET)    &lt;br /&gt;&lt;a href="http://www.jython.org/%20"&gt;Jython&lt;/a&gt; (Python running on the Java Virtual Machine)    &lt;br /&gt;&lt;a href="http://pypy.org/"&gt;PyPy&lt;/a&gt; (A fast python implementation with a JIT compiler)    &lt;br /&gt;&lt;a href="http://www.stackless.com/%20"&gt;Stackless Python&lt;/a&gt; (Branch of CPython supporting microthreads) &lt;/p&gt;  &lt;p&gt;Ver la implementación web: &lt;a href="http://webpython.codepoint.net/wsgi_tutorial"&gt;http://webpython.codepoint.net/wsgi_tutorial&lt;/a&gt; madre de otras implementaciones como Rack en Ruby, y OWIN en .NET &lt;/p&gt;  &lt;p&gt;Mis enlaces: &lt;a href="http://delicious.com/ajlopez/python"&gt;http://delicious.com/ajlopez/python&lt;/a&gt;    &lt;br /&gt;Mis posts: &lt;a href="http://ajlopez.wordpress.com/category/python/"&gt;http://ajlopez.wordpress.com/category/python/&lt;/a&gt;&lt;/p&gt;  &lt;h3&gt;Patrones encontrados &lt;/h3&gt;  &lt;p&gt;Existencia de REPL: todos   &lt;br /&gt;Compilación a otro lenguaje: Scala, Clojure, usando la máquina virtual y librerías de clases existentes    &lt;br /&gt;Pasaje de Mensajes: Erlang    &lt;br /&gt;Módulos: todos    &lt;br /&gt;Actores: Scala, algo también en Clojure y Erlang    &lt;br /&gt;Software Transactional Memory: Clojure &lt;/p&gt;  &lt;p&gt;Bueno, espero que les haya dado un panorama de que hay vida más allá de C# y Java ;-)&lt;/p&gt;  &lt;p&gt;Nos leemos! &lt;/p&gt;  &lt;p&gt;Angel “Java” Lopez   &lt;br /&gt;&lt;a href="http://www.ajlopez.com"&gt;http://www.ajlopez.com&lt;/a&gt;    &lt;br /&gt;http://twitter.com/ajlopez&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1806851" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/Lenguajes+de+Programaci_26002300_243_3B00_n/default.aspx">Lenguajes de Programaci&amp;#243;n</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Scala/default.aspx">Scala</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Python/default.aspx">Python</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Javascript/default.aspx">Javascript</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/NodeJs/default.aspx">NodeJs</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Ruby/default.aspx">Ruby</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Rails/default.aspx">Rails</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Erlang/default.aspx">Erlang</category></item><item><title>Ruby on Rails, Aplicación de Demo (1) Creando la Aplicación</title><link>http://msmvps.com/blogs/lopez/archive/2012/02/09/ruby_2D00_on_2D00_rails_2D00_demo_2D00_application_2D00_1_2D00_creating_2D00_the_2D00_application.aspx</link><pubDate>Thu, 09 Feb 2012 17:32:35 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1805837</guid><dc:creator>lopez</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1805837</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2012/02/09/ruby_2D00_on_2D00_rails_2D00_demo_2D00_application_2D00_1_2D00_creating_2D00_the_2D00_application.aspx#comments</comments><description>&lt;p&gt;Ya estuve escribiendo una serie de posts sobre mi experiencia en el pasado Ruby Fun Day en Buenos Aires:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2011/11/08/mi-d-237-a-en-el-ruby-fun-day-1-la-history-de-stephen-anderson.aspx"&gt;Mi Día en el Ruby Fun Day&lt;/a&gt; con &lt;a href="http://twitter.com/bendycode"&gt;@bendycode&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Ahora quiero comenzar a pasar en limpio mis pasos de aprendizaje estudiando el capítuylo 2 del libro de&amp;#160; &lt;a href="http://www.michaelhartl.com/"&gt;Michael Hartl&lt;/a&gt; : &lt;a href="http://ruby.railstutorial.org/ruby-on-rails-tutorial-book"&gt;Ruby on Rails Tutorial: Learn from Example&lt;/a&gt;. Yo estoy siguiéndolo con la versión 3 de Ruby on Rails.&lt;/p&gt;  &lt;p&gt;Ya había instalado Ruby en mi máquina Windows, usando &lt;a href="http://rubyinstaller.org/"&gt;http://rubyinstaller.org/&lt;/a&gt; (otras opciones en &lt;a href="http://www.ruby-lang.org/en/downloads/"&gt;http://www.ruby-lang.org/en/downloads/&lt;/a&gt;). En Windows, debemos instalar también DevKit (un “minimalist GNU for windows” (mingw)). Vean la página de Ruby Installer para el enlace de bajada. Las instrucciones para instalarlo están en &lt;a title="http://github.com/oneclick/rubyinstaller/wiki/Development-Kit" href="http://github.com/oneclick/rubyinstaller/wiki/Development-Kit"&gt;http://github.com/oneclick/rubyinstaller/wiki/Development-Kit&lt;/a&gt;. (&lt;a href="http://msmvps.com/blogs/lopez/archive/2011/11/14/mi-d-237-a-en-el-ruby-fun-day-3-creando-una-aplicaci-243-n-rails-3.aspx"&gt;otros detalles&lt;/a&gt;).&lt;/p&gt;  &lt;p&gt;Luego de todo eso, ejecuté el comando para instalar rails, en cualquier command prompt:&lt;/p&gt;  &lt;p&gt;&lt;font size="3" face="Consolas"&gt;gem install rails&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;lo que instala Ruby on Rails, el framework de desarrollo de sitios web escrito en Ruby. Vean que es una gema (gem) que se instala como cualquier otra estando en línea. Ahora vamos a un directorio de trabajo (en mi caso c:\Git), donde ejecutamos&lt;/p&gt;  &lt;p&gt;&lt;font size="3" face="Consolas"&gt;rails&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;Salida:&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/rubyfunday11.png" alt="" /&gt; &lt;/p&gt;  &lt;p&gt;Luego ejecuté&lt;/p&gt;  &lt;p&gt;&lt;font size="3" face="Consolas"&gt;rails new RailsDemoApp&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;con salida:&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/rails01.png" alt="" /&gt; &lt;/p&gt;  &lt;p&gt;Eso crea un nuevo directorio, me cambio a ese:&lt;/p&gt;  &lt;p&gt;&lt;font size="3" face="Consolas"&gt;cd RailsDemoApp&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;Este es el árbol de directorios que tengo:&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/rubyfunday20.png" alt="" /&gt; &lt;/p&gt;  &lt;p&gt;Ruby maneja gemas (paquetes a instalar). Como vimos, Rails mismo es una gema. Y una aplicación Rails, como la recién creada, tiene un archivo GemFile donde se especifican las gemas que esta nueva aplicación necesita. Es usual entonces apelar a un programa que revisa ese archivo e instala cualquier gema que se necesite y no esté instalada. Ejecuto:&lt;/p&gt;  &lt;p&gt;&lt;font size="3" face="Consolas"&gt;bundle install&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;Bundle es el nuevo instalador de paquetes que usa Ruby on Rails 3. Lee el archivo GemFile e instala (en el directorio de Ruby, en nuestra máquina, no en el directorio de la aplicació) las gemas que necesite. Ahora podemos ejecutar:&lt;/p&gt;  &lt;p&gt;&lt;font size="3" face="Consolas"&gt;bundle show&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/rails02.png" alt="" /&gt; &lt;/p&gt;  &lt;p&gt;Configuré el directorio actual (Git\RailsDemoApp) para que sea un repositorio Git:&lt;/p&gt;  &lt;p&gt;&lt;font size="3" face="Consolas"&gt;git init      &lt;br /&gt;git add .       &lt;br /&gt;git commit –m “Initial Commit”&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;Agregué un nuevo repositorio en mi cuenta de GitHub usando &lt;a title="https://github.com/repositories/new" href="https://github.com/repositories/new"&gt;https://github.com/repositories/new&lt;/a&gt;:&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/rails03.png" alt="" /&gt; &lt;/p&gt;  &lt;p&gt;El nuevo repo: &lt;a href="https://github.com/ajlopez/RailsDemoApp"&gt;https://github.com/ajlopez/RailsDemoApp&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Lo agregué como repositorio remoto a mi repo local, y envié lo que tengo a GitHub:&lt;/p&gt;  &lt;p&gt;&lt;font size="3" face="Consolas"&gt;git remote add origin &lt;/font&gt;&lt;a href="mailto:git@github.com:ajlopez/RailsDemoApp.git"&gt;&lt;font size="3" face="Consolas"&gt;git@github.com:ajlopez/RailsDemoApp.git&lt;/font&gt;&lt;/a&gt;     &lt;br /&gt;&lt;font size="3" face="Consolas"&gt;git push origin master&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;Ya desde la instalación de bundle, podemos lanzar el servidor con&lt;/p&gt;  &lt;p&gt;&lt;font size="3" face="Consolas"&gt;rails server&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;o en su forma corta&lt;/p&gt;  &lt;p&gt;&lt;font size="3" face="Consolas"&gt;rails s&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;Veo el resultado en &lt;a href="http://localhost:3000"&gt;http://localhost:3000&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/rubyfunday28.png" alt="" /&gt; &lt;/p&gt;  &lt;p&gt;Próximos pasos, para siguientes posts: agregar un modelo simple (usuarios, y microposts, con relación uno a varios), base de datos, vistas, controladores, “scaffolding”, y despliegue en Heroku. El Scaffolding (generació de código para CRUD) será la aproximación a usar en los próximos posts, como en el libro de Hartl, pero despues me gustaría escribir sobre cómo construir un sitio Rails paso a paso, como hace el mismo Hartl a partir del capítulo 3 de su libro.&lt;/p&gt;  &lt;p&gt;Nos leemos!&lt;/p&gt;  &lt;p&gt;Angel “Java” Lopez    &lt;br /&gt;&lt;a href="http://www.ajlopez.com"&gt;http://www.ajlopez.com&lt;/a&gt;     &lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1805837" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/Desarrollo+Web/default.aspx">Desarrollo Web</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Ruby/default.aspx">Ruby</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Rails/default.aspx">Rails</category></item><item><title>Mi Día en el Ruby Fun Day (7) Primer Modelo</title><link>http://msmvps.com/blogs/lopez/archive/2012/02/04/mi-d-237-a-en-el-ruby-fun-day-7-primer-modelo.aspx</link><pubDate>Sat, 04 Feb 2012 18:01:31 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1805632</guid><dc:creator>lopez</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1805632</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2012/02/04/mi-d-237-a-en-el-ruby-fun-day-7-primer-modelo.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2011/11/25/mi-d-237-a-en-el-ruby-fun-day-6-rake-y-bundler.aspx"&gt;Anterior Post&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Una de las grandes “features” de Rails es poder generar código, definiendo un modelo simple. En el curso decidimos implementar una lista de charlas, con oradores. Para Orador, definimos modelo Speaker y se generó código con:&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/rubyfunday34.png" alt="" /&gt; &lt;/p&gt;  &lt;p&gt;La clave es la opción &lt;strong&gt;generate&lt;/strong&gt; del comando &lt;strong&gt;rails&lt;/strong&gt;. Con esa opción se pueden generar distintos archivos de texto, con &lt;strong&gt;scaffold&lt;/strong&gt; genera los controladores, vistas, y modelos, con acceso a datos, de un modelo simple. El modelo se describe con &lt;strong&gt;Speaker name:string&lt;/strong&gt; (se pueden poner más campos de distintos tipos).&lt;/p&gt;  &lt;p&gt;Generó varios archivos, como &lt;strong&gt;app/models/speaker.rb&lt;/strong&gt;:&lt;/p&gt;  &lt;pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;&lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; Speaker &amp;lt; ActiveRecord::Base&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;&lt;span style="color:#0000ff;"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;O el controlador app/controllers/speakers_controller.rb:&lt;/p&gt;

&lt;pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;&lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; SpeakersController &amp;lt; ApplicationController
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;  &lt;span style="color:#008000;"&gt;# GET /speakers&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;  &lt;span style="color:#008000;"&gt;# GET /speakers.json&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;  &lt;span style="color:#0000ff;"&gt;def&lt;/span&gt; index
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;    @speakers = Speaker.all
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;    respond_to &lt;span style="color:#0000ff;"&gt;do&lt;/span&gt; |&lt;span style="color:#00008b;"&gt;format&lt;/span&gt;|
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;      &lt;span style="color:#00008b;"&gt;format&lt;/span&gt;.html &lt;span style="color:#008000;"&gt;# index.html.erb&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;      &lt;span style="color:#00008b;"&gt;format&lt;/span&gt;.json { render json: @speakers }
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;    &lt;span style="color:#0000ff;"&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;  &lt;span style="color:#0000ff;"&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;  &lt;span style="color:#008000;"&gt;# GET /speakers/1&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;  &lt;span style="color:#008000;"&gt;# GET /speakers/1.json&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;  &lt;span style="color:#0000ff;"&gt;def&lt;/span&gt; show
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;    @speaker = Speaker.find(params[:id])
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;    respond_to &lt;span style="color:#0000ff;"&gt;do&lt;/span&gt; |&lt;span style="color:#00008b;"&gt;format&lt;/span&gt;|
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;      &lt;span style="color:#00008b;"&gt;format&lt;/span&gt;.html &lt;span style="color:#008000;"&gt;# show.html.erb&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;      &lt;span style="color:#00008b;"&gt;format&lt;/span&gt;.json { render json: @speaker }
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;    &lt;span style="color:#0000ff;"&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;  &lt;span style="color:#0000ff;"&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;  &lt;span style="color:#008000;"&gt;# GET /speakers/new&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;  &lt;span style="color:#008000;"&gt;# GET /speakers/new.json&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;  &lt;span style="color:#0000ff;"&gt;def&lt;/span&gt; new
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;    @speaker = Speaker.new
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;    respond_to &lt;span style="color:#0000ff;"&gt;do&lt;/span&gt; |&lt;span style="color:#00008b;"&gt;format&lt;/span&gt;|
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;      &lt;span style="color:#00008b;"&gt;format&lt;/span&gt;.html &lt;span style="color:#008000;"&gt;# new.html.erb&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;      &lt;span style="color:#00008b;"&gt;format&lt;/span&gt;.json { render json: @speaker }
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;    &lt;span style="color:#0000ff;"&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;  &lt;span style="color:#0000ff;"&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;  &lt;span style="color:#008000;"&gt;# GET /speakers/1/edit&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;  &lt;span style="color:#0000ff;"&gt;def&lt;/span&gt; edit
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;    @speaker = Speaker.find(params[:id])
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;  &lt;span style="color:#0000ff;"&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;  &lt;span style="color:#008000;"&gt;# POST /speakers&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;  &lt;span style="color:#008000;"&gt;# POST /speakers.json&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;  &lt;span style="color:#0000ff;"&gt;def&lt;/span&gt; create
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;    @speaker = Speaker.new(params[:speaker])
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;    respond_to &lt;span style="color:#0000ff;"&gt;do&lt;/span&gt; |&lt;span style="color:#00008b;"&gt;format&lt;/span&gt;|
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;      &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; @speaker.save
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;        &lt;span style="color:#00008b;"&gt;format&lt;/span&gt;.html { redirect_to @speaker, notice: &amp;#39;Speaker was successfully created.&amp;#39; }
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;        &lt;span style="color:#00008b;"&gt;format&lt;/span&gt;.json { render json: @speaker, status: :created, location: @speaker }
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;      &lt;span style="color:#0000ff;"&gt;else&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;        &lt;span style="color:#00008b;"&gt;format&lt;/span&gt;.html { render action: &amp;quot;&lt;span style="color:#8b0000;"&gt;new&lt;/span&gt;&amp;quot; }
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;        &lt;span style="color:#00008b;"&gt;format&lt;/span&gt;.json { render json: @speaker.errors, status: :unprocessable_entity }
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;      &lt;span style="color:#0000ff;"&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;    &lt;span style="color:#0000ff;"&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;  &lt;span style="color:#0000ff;"&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;  &lt;span style="color:#008000;"&gt;# PUT /speakers/1&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;  &lt;span style="color:#008000;"&gt;# PUT /speakers/1.json&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;  &lt;span style="color:#0000ff;"&gt;def&lt;/span&gt; update
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;    @speaker = Speaker.find(params[:id])
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;    respond_to &lt;span style="color:#0000ff;"&gt;do&lt;/span&gt; |&lt;span style="color:#00008b;"&gt;format&lt;/span&gt;|
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;      &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; @speaker.update_attributes(params[:speaker])
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;        &lt;span style="color:#00008b;"&gt;format&lt;/span&gt;.html { redirect_to @speaker, notice: &amp;#39;Speaker was successfully updated.&amp;#39; }
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;        &lt;span style="color:#00008b;"&gt;format&lt;/span&gt;.json { head :ok }
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;      &lt;span style="color:#0000ff;"&gt;else&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;        &lt;span style="color:#00008b;"&gt;format&lt;/span&gt;.html { render action: &amp;quot;&lt;span style="color:#8b0000;"&gt;edit&lt;/span&gt;&amp;quot; }
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;        &lt;span style="color:#00008b;"&gt;format&lt;/span&gt;.json { render json: @speaker.errors, status: :unprocessable_entity }
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;      &lt;span style="color:#0000ff;"&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;    &lt;span style="color:#0000ff;"&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;  &lt;span style="color:#0000ff;"&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;  &lt;span style="color:#008000;"&gt;# DELETE /speakers/1&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;  &lt;span style="color:#008000;"&gt;# DELETE /speakers/1.json&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;  &lt;span style="color:#0000ff;"&gt;def&lt;/span&gt; destroy
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;    @speaker = Speaker.find(params[:id])
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;    @speaker.destroy
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;    respond_to &lt;span style="color:#0000ff;"&gt;do&lt;/span&gt; |&lt;span style="color:#00008b;"&gt;format&lt;/span&gt;|
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;      &lt;span style="color:#00008b;"&gt;format&lt;/span&gt;.html { redirect_to speakers_url }
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;      &lt;span style="color:#00008b;"&gt;format&lt;/span&gt;.json { head :ok }
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;    &lt;span style="color:#0000ff;"&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;  &lt;span style="color:#0000ff;"&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;&lt;span style="color:#0000ff;"&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;Y distintas vistas en app/views/speakers como index.html.erb:&lt;/p&gt;

&lt;pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;h1&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;Listing speakers&lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;h1&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;table&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;  &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;tr&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;    &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;th&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;Name&lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;th&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;    &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;th&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;th&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;    &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;th&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;th&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;    &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;th&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;th&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;  &lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;tr&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;% @speakers.each do |speaker| %&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;  &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;tr&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;    &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;td&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;%= speaker.name %&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;td&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;    &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;td&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;%= link_to &amp;#39;Show&amp;#39;, speaker %&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;td&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;    &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;td&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;%= link_to &amp;#39;Edit&amp;#39;, edit_speaker_path(speaker) %&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;td&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;    &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;td&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;%= link_to &amp;#39;Destroy&amp;#39;, speaker, confirm: &amp;#39;Are you sure?&amp;#39;, method: :delete %&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;td&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;  &lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;tr&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;% end %&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;table&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;br&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;/&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;%= link_to &amp;#39;New Speaker&amp;#39;, new_speaker_path %&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;Luego, levantamos el servidor de nuevo con:&lt;/p&gt;

&lt;p&gt;&lt;font size="3"&gt;rails server&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;Levanta el servidor como antes, pero si navegamos a &lt;a href="http://localhost:3000/speakers"&gt;http://localhost:3000/speakers&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/rubyfunday35.png" alt="" /&gt; &lt;/p&gt;

&lt;p&gt;Resulta que se generó código para soportar una lista de oradores, y una tabla de oradores en la base de datos, pero esta última todavía está vacía, sin la tabla correspondiente. El generador de código de Rails se encargó de dejar también los comandos de actualización de la base. Ejecutamos:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/rubyfunday36.png" alt="" /&gt; &lt;/p&gt;

&lt;p&gt;Vean que crea la tabla de Speakers (ver el directorio db/migrate donde quedó un archivo que define el paso 20111218214020_create_speakers.rb:&lt;/p&gt;

&lt;pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;&lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; CreateSpeakers &amp;lt; ActiveRecord::Migration
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;  &lt;span style="color:#0000ff;"&gt;def&lt;/span&gt; change
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;    create_table :speakers &lt;span style="color:#0000ff;"&gt;do&lt;/span&gt; |t|
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;      t.string :name&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;      
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;      t.timestamps
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;    &lt;span style="color:#0000ff;"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;  &lt;span style="color:#0000ff;"&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;&lt;span style="color:#0000ff;"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;Noten que el nombre del archivo tiene la fecha/hora de creación, para luego reproducir en orden los comandos contra la base de datos para que ésta quede actualizada. Ahora, navegamos de nuevo a &lt;a href="http://localhost:3000/speakers"&gt;http://localhost:3000/speakers&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/rubyfunday38.png" alt="" /&gt; &lt;/p&gt;

&lt;p&gt;Puedo dar de alta un orador:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/rubyfunday40.png" alt="" /&gt; &lt;/p&gt;

&lt;p&gt;Y el resultado es:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/rubyfunday39.png" alt="" /&gt; &lt;/p&gt;

&lt;p&gt;Bien! Ya tenemos nuestro primer modelo simple, y las páginas (noten las URLs que se formaron) para manejarlo.&lt;/p&gt;

&lt;p&gt;Próximos temas: extendiendo el modelo, relaciones uno a varios, desplegando en Heroku.&lt;/p&gt;

&lt;p&gt;Nos leemos!&lt;/p&gt;

&lt;p&gt;Angel “Java” Lopez
  &lt;br /&gt;&lt;a href="http://www.ajlopez.com"&gt;http://www.ajlopez.com&lt;/a&gt;

  &lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1805632" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/Desarrollo+de+Software/default.aspx">Desarrollo de Software</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Desarrollo+Web/default.aspx">Desarrollo Web</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Ruby/default.aspx">Ruby</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Rails/default.aspx">Rails</category></item><item><title>Mi Día en el Ruby Fun Day (6) Rake y Bundler</title><link>http://msmvps.com/blogs/lopez/archive/2011/11/25/mi-d-237-a-en-el-ruby-fun-day-6-rake-y-bundler.aspx</link><pubDate>Fri, 25 Nov 2011 10:06:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1802896</guid><dc:creator>lopez</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1802896</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2011/11/25/mi-d-237-a-en-el-ruby-fun-day-6-rake-y-bundler.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2011/11/22/mi-d-237-a-en-el-ruby-fun-day-5-lanzando-rails.aspx"&gt;Anterior Post&lt;/a&gt; &lt;br /&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2012/02/04/mi-d-237-a-en-el-ruby-fun-day-7-primer-modelo.aspx"&gt;Siguiente Post&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Una de las utilidades que viene con el Ruby Installer es el rake. Rake es un &amp;ldquo;make&amp;rdquo; para Ruby. Se basa en leer un Rakefile donde se definen las tareas. Notablemente, ese archivo es c&amp;oacute;digo Ruby. Rails nos dej&amp;oacute; este archivo en el directorio de nuestra aplicaci&amp;oacute;n.&lt;/p&gt;
&lt;pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,courier,monospace;font-size:12px;"&gt;&lt;span style="color:#008000;"&gt;#!/usr/bin/env rake&lt;/span&gt;
&lt;span style="color:#008000;"&gt;# Add your own tasks in files placed in lib/tasks ending in .rake,&lt;/span&gt;
&lt;span style="color:#008000;"&gt;# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.&lt;/span&gt;
&lt;span style="color:#00008b;"&gt;require&lt;/span&gt; &lt;a href="http://www.ruby-doc.org/docs/rdoc/1.9/classes/File.html" style="color:#ff0000;"&gt;File&lt;/a&gt;.expand_path(&amp;#39;../config/application&amp;#39;, &lt;span style="color:#0000ff;"&gt;__FILE__&lt;/span&gt;)
MyRails::Application.load_tasks
&lt;/pre&gt;
&lt;/pre&gt;
&lt;p&gt;El m&amp;eacute;todo load_tasks no est&amp;aacute; definido directamente en &lt;strong&gt;MyRails::Application &lt;/strong&gt;(que est&amp;aacute; definida en &lt;strong&gt;config/application.rb&lt;/strong&gt;) sino que se hereda de &lt;strong&gt;Rails::Application&lt;/strong&gt;. Pero uno podr&amp;iacute;a sobreescribir el m&amp;eacute;todo.&lt;/p&gt;
&lt;p&gt;Si ejecutamos &lt;strong&gt;rake &amp;ndash;T&lt;/strong&gt; tenemos la lista de tareas que reconoce:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/rubyfunday29.png" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;Vean que hay tareas para crear la base de datos, y para migrarla cuando tengamos nuevas tablas. Ya lo haremos cuando definamos alg&amp;uacute;n modelo. Probemos ahora &lt;strong&gt;rake stats&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/rubyfunday30.png" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;Nos muestra la cantidad de controladores, clases, l&amp;iacute;neas de c&amp;oacute;digo, m&amp;eacute;todos, etc.&lt;/p&gt;
&lt;p&gt;Otro archivo (que apareci&amp;oacute;n en Rails 3.x ver &lt;a href="http://edgeguides.rubyonrails.org/3_0_release_notes.html"&gt;http://edgeguides.rubyonrails.org/3_0_release_notes.html&lt;/a&gt;) es el Gemfile:&lt;/p&gt;
&lt;pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,courier,monospace;font-size:12px;"&gt;source &amp;#39;http://rubygems.org&amp;#39;
gem &amp;#39;rails&amp;#39;, &amp;#39;3.1.1&amp;#39;
&lt;span style="color:#008000;"&gt;# Bundle edge Rails instead:&lt;/span&gt;
&lt;span style="color:#008000;"&gt;# gem &amp;#39;rails&amp;#39;,     :git =&amp;gt; &amp;#39;git://github.com/rails/rails.git&amp;#39;&lt;/span&gt;
gem &amp;#39;sqlite3&amp;#39;
&lt;span style="color:#008000;"&gt;# Gems used only for assets and not required&lt;/span&gt;
&lt;span style="color:#008000;"&gt;# in production environments by default.&lt;/span&gt;
group :assets &lt;span style="color:#0000ff;"&gt;do&lt;/span&gt;
  gem &amp;#39;sass-rails&amp;#39;,   &amp;#39;~&amp;gt; 3.1.4&amp;#39;
  gem &amp;#39;coffee-rails&amp;#39;, &amp;#39;~&amp;gt; 3.1.1&amp;#39;
  gem &amp;#39;uglifier&amp;#39;, &amp;#39;&amp;gt;= 1.0.3&amp;#39;
&lt;span style="color:#0000ff;"&gt;end&lt;/span&gt;
gem &amp;#39;jquery-rails&amp;#39;
&lt;span style="color:#008000;"&gt;# To use ActiveModel has_secure_password&lt;/span&gt;
&lt;span style="color:#008000;"&gt;# gem &amp;#39;bcrypt-ruby&amp;#39;, &amp;#39;~&amp;gt; 3.0.0&amp;#39;&lt;/span&gt;
&lt;span style="color:#008000;"&gt;# Use unicorn as the web server&lt;/span&gt;
&lt;span style="color:#008000;"&gt;# gem &amp;#39;unicorn&amp;#39;&lt;/span&gt;
&lt;span style="color:#008000;"&gt;# Deploy with 
&lt;/span&gt;
&lt;span style="color:#008000;"&gt;# gem &amp;#39;
&lt;/span&gt;
&amp;#39;
&lt;span style="color:#008000;"&gt;# To use debugger&lt;/span&gt;
&lt;span style="color:#008000;"&gt;# gem &amp;#39;ruby-debug19&amp;#39;, :require =&amp;gt; &amp;#39;ruby-debug&amp;#39;&lt;/span&gt;
group :&lt;span style="color:#00008b;"&gt;test&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;do&lt;/span&gt;
  &lt;span style="color:#008000;"&gt;# Pretty printed test output&lt;/span&gt;
  gem &amp;#39;turn&amp;#39;, :&lt;span style="color:#00008b;"&gt;require&lt;/span&gt; =&amp;gt; &lt;span style="color:#0000ff;"&gt;false&lt;/span&gt;
&lt;span style="color:#0000ff;"&gt;end&lt;/span&gt;
&lt;/pre&gt;
&lt;/pre&gt;
&lt;p&gt;Es un archivo que define que gemas vamos a usar en nuestra aplicaci&amp;oacute;n. Este archivo es consumido por Bundler:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/carlhuda/bundler"&gt;https://github.com/carlhuda/bundler&lt;/a&gt; &lt;br /&gt;&lt;a href="http://gembundler.com/"&gt;http://gembundler.com/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Si ejecutamos &lt;strong&gt;bundle&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/rubyfunday31.png" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;Al final dice:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/rubyfunday32.png" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;As&amp;iacute;, con &lt;strong&gt;bundle show sqlite3&lt;/strong&gt; obtenemos:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/rubyfunday33.png" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;Vean que deja un archivo &lt;strong&gt;Gemfile.lock&lt;/strong&gt; con informaci&amp;oacute;n de las gemas que termina usando.&lt;/p&gt;
&lt;p&gt;Vayan notando la manera que trabaja el ecosistema de Ruby (con gemas) y Rails (adoptando algunas gemas para sus tareas). Tambi&amp;eacute;n noten que todo evoluciona: el Rails que estoy probando (versi&amp;oacute;n 3.1.1) tiene bundler, cuando los anteriores (2.x) no lo ten&amp;iacute;an. &lt;/p&gt;
&lt;p&gt;Pr&amp;oacute;ximos posts: armar un modelo sencillo, crear la base, probarlo, modificarlo, migrar la base, publicar.&lt;/p&gt;
&lt;p&gt;Nos leemos!&lt;/p&gt;
&lt;p&gt;Angel &amp;ldquo;Java&amp;rdquo; Lopez &lt;br /&gt;&lt;a href="http://www.ajlopez.com"&gt;http://www.ajlopez.com&lt;/a&gt; &lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1802896" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/Desarrollo+de+Software/default.aspx">Desarrollo de Software</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Desarrollo+Web/default.aspx">Desarrollo Web</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Ruby/default.aspx">Ruby</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Rails/default.aspx">Rails</category></item><item><title>Mi Día en el Ruby Fun Day (5) Lanzando Rails</title><link>http://msmvps.com/blogs/lopez/archive/2011/11/22/mi-d-237-a-en-el-ruby-fun-day-5-lanzando-rails.aspx</link><pubDate>Tue, 22 Nov 2011 10:35:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1802800</guid><dc:creator>lopez</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1802800</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2011/11/22/mi-d-237-a-en-el-ruby-fun-day-5-lanzando-rails.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2011/11/15/mi-d-237-a-en-el-ruby-fun-day-4-usando-git.aspx"&gt;Anterior Post&lt;/a&gt;     &lt;br /&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2011/11/25/mi-d-237-a-en-el-ruby-fun-day-6-rake-y-bundler.aspx"&gt;Siguiente Post&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Ahora ya tenemos generado nuestro primer sitio Rails. Recordemos la estructura:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/rubyfunday20.png" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;Vamos a ver que Rails se basa en Modelo-Vista-Controlador. Vean el primer controlador que tenemos disponible &lt;strong&gt;\MyRails\app\controllers\application_controller.rb&lt;/strong&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,courier,monospace;font-size:12px;"&gt;&lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; ApplicationController &amp;lt; ActionController::Base
  protect_from_forgery&lt;span style="color:#0000ff;"&gt;end&lt;/span&gt;&lt;/pre&gt;
&lt;/pre&gt;
&lt;p&gt;Vean &lt;strong&gt;\MyRails\app\views\layout\application_view.rb&lt;/strong&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,courier,monospace;font-size:12px;"&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;!DOCTYPE html&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;html&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;head&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
  &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;title&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;MyRails&lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;title&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
  &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;%= stylesheet_link_tag    &amp;quot;application&amp;quot; %&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
  &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;%= javascript_include_tag &amp;quot;application&amp;quot; %&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
  &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;%= csrf_meta_tags %&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;head&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;body&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;%= yield %&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;body&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;html&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;
&lt;/pre&gt;
&lt;p&gt;Vamos a ver que lo de arriba est&amp;aacute; escrito en un lenguaje de templates (&lt;strong&gt;ERB&lt;/strong&gt;) nativo de Ruby, que permite insertar c&amp;oacute;digo en el medio de texto (jeje&amp;hellip; &lt;a href="http://msmvps.com/blogs/lopez/archive/2011/11/19/ajgenesis_2D00_basis_2D00_of_2D00_its_2D00_implementation.aspx"&gt;por qu&amp;eacute; no me sorprende&lt;/a&gt; ;-). Pero todo esto todav&amp;iacute;a no se est&amp;aacute; usando. La aplicaci&amp;oacute;n generada tiene un simple index.html en el directorio public.&lt;/p&gt;
&lt;p&gt;Si ejecutamos &lt;strong&gt;rails&lt;/strong&gt; en la l&amp;iacute;nea de comando:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/rubyfunday26.png" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;Hay varios subcomandos a explorar. El m&amp;aacute;s interesante ser&amp;aacute; el &lt;strong&gt;generate&lt;/strong&gt; que permite ir generando c&amp;oacute;digo (vieron la luz! ;-) desde un modelo que vamos definiendo por l&amp;iacute;nea de comando. Hoy probamos &lt;strong&gt;rails server:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/rubyfunday27.png" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;Levanta un servidor web (veremos que Rails se basa en otras gemas, como WEBRick para conseguir esto). Podemos verlo en &lt;a href="http://localhost:3000"&gt;http://localhost:3000&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/rubyfunday28.png" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;Pr&amp;oacute;ximo paso recomendado es el &lt;strong&gt;rails generate&lt;/strong&gt;. En el curso generamos un modelo simple con charlas y oradores. Veremos algo as&amp;iacute; en los pr&amp;oacute;ximos posts. Tengo que estudiar las rutas, y las distintas opciones de &lt;strong&gt;rake&lt;/strong&gt; que nos van quedando (pueden espiar el &lt;strong&gt;Rakefile&lt;/strong&gt; que qued&amp;oacute; generado en el directorio &lt;strong&gt;MyRails&lt;/strong&gt;, mientras tanto)&lt;/p&gt;
&lt;p&gt;Nos leemos!&lt;/p&gt;
&lt;p&gt;Angel &amp;ldquo;Java&amp;rdquo; Lopez 
  &lt;br /&gt;&lt;a href="http://www.ajlopez.com"&gt;http://www.ajlopez.com&lt;/a&gt; 
  &lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1802800" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/Desarrollo+de+Software/default.aspx">Desarrollo de Software</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Desarrollo+Web/default.aspx">Desarrollo Web</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Ruby/default.aspx">Ruby</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Rails/default.aspx">Rails</category></item><item><title>Mi Día en el Ruby Fun Day (4) Usando Git</title><link>http://msmvps.com/blogs/lopez/archive/2011/11/15/mi-d-237-a-en-el-ruby-fun-day-4-usando-git.aspx</link><pubDate>Tue, 15 Nov 2011 11:06:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1802504</guid><dc:creator>lopez</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1802504</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2011/11/15/mi-d-237-a-en-el-ruby-fun-day-4-usando-git.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2011/11/14/mi-d-237-a-en-el-ruby-fun-day-3-creando-una-aplicaci-243-n-rails-3.aspx"&gt;Anterior Post&lt;/a&gt;    &lt;br /&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2011/11/22/mi-d-237-a-en-el-ruby-fun-day-5-lanzando-rails.aspx"&gt;Siguiente Post&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Un punto que Stephen Anderson us&amp;oacute; todo el tiempo, es Git. Yo ya lo ten&amp;iacute;a instalado en mi m&amp;aacute;quina. Lo pueden instalar desde:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://code.google.com/p/msysgit/downloads/list" title="http://code.google.com/p/msysgit/downloads/list"&gt;http://code.google.com/p/msysgit/downloads/list&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Lo configur&amp;eacute; en su tiempo para que estuviera en el Path (el instalador pregunta si quieren esa opci&amp;oacute;n). Si quieren un cliente gr&amp;aacute;fico, pueden usar:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://code.google.com/p/tortoisegit/downloads/list" title="http://code.google.com/p/tortoisegit/downloads/list"&gt;http://code.google.com/p/tortoisegit/downloads/list&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Luego de creada la aplicaci&amp;oacute;n Rails (que todav&amp;iacute;a no lanzamos), me cambi&amp;eacute; al directorio de la misma, y lo prepar&amp;eacute; para ser un repositorio git:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/rubyfunday21.png" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;El &lt;strong&gt;git add .&lt;/strong&gt; agrega los archivos del directorio actual (y subdirectorios) a lo que se llama el &amp;ldquo;index&amp;rdquo; de git: digamos un &amp;aacute;rea de &amp;ldquo;staging&amp;rdquo; antes del commit. El directorio de la aplicaci&amp;oacute;n es ahora el &amp;ldquo;working directory&amp;rdquo;. Pero no se hace commit de ese directorio, sino de lo que est&amp;aacute; en el &amp;ldquo;index&amp;rdquo;. De ah&amp;iacute; la necesidad del comando &lt;strong&gt;add&lt;/strong&gt;: decirle a git cu&amp;aacute;les archivos del &amp;ldquo;working directory&amp;rdquo; se agregan al &amp;ldquo;index&amp;rdquo; para ser enviados en el pr&amp;oacute;ximo commit en el repositorio local (recuerden: git tiene repositorio local).&lt;/p&gt;
&lt;p&gt;El primer commit:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/rubyfunday22.png" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;El &lt;strong&gt;&amp;ndash;m&lt;/strong&gt; permite poner el mensaje de commit.&lt;/p&gt;
&lt;p&gt;Como quiero tener el c&amp;oacute;digo tambi&amp;eacute;n en mi repositorio de Github, y no s&amp;oacute;lo en mi m&amp;aacute;quina, cre&amp;eacute; un repositorio en GitHub:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/rubyfunday23.png" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;Con este comando agrego un nuevo repositorio remoto de este proyecto (pueden tener varios), llamado tradicionalmente &amp;ldquo;origin&amp;rdquo;:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/rubyfunday24.png" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;Es tiempo de enviar lo que est&amp;aacute; en el repositorio local al remoto:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/rubyfunday25.png" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;Pueden ver el estado de mi repositorio remoto en:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/ajlopez/MyRails" title="https://github.com/ajlopez/MyRails"&gt;https://github.com/ajlopez/MyRails&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Pr&amp;oacute;ximos posts: levantar y probar la aplicaci&amp;oacute;n Rails, generar un modelo.&lt;/p&gt;
&lt;p&gt;Nos leemos!&lt;/p&gt;
&lt;p&gt;Angel &amp;ldquo;Java&amp;rdquo; Lopez   &lt;br /&gt;&lt;a href="http://www.ajlopez.com"&gt;http://www.ajlopez.com&lt;/a&gt;    &lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1802504" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/Desarrollo+de+Software/default.aspx">Desarrollo de Software</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Desarrollo+Web/default.aspx">Desarrollo Web</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Git/default.aspx">Git</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Ruby/default.aspx">Ruby</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Rails/default.aspx">Rails</category></item><item><title>Mi Día en el Ruby Fun Day (3) Creando una aplicación Rails 3</title><link>http://msmvps.com/blogs/lopez/archive/2011/11/14/mi-d-237-a-en-el-ruby-fun-day-3-creando-una-aplicaci-243-n-rails-3.aspx</link><pubDate>Mon, 14 Nov 2011 08:23:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1802444</guid><dc:creator>lopez</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1802444</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2011/11/14/mi-d-237-a-en-el-ruby-fun-day-3-creando-una-aplicaci-243-n-rails-3.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2011/11/12/mi-d-237-a-en-el-ruby-fun-day-2-instalando-ruby-y-rails.aspx" target="_blank"&gt;Anterior Post&lt;/a&gt;     &lt;br /&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2011/11/15/mi-d-237-a-en-el-ruby-fun-day-4-usando-git.aspx"&gt;Siguiente Post&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;En el anterior post, llegu&amp;eacute; a instalar Rails. Ahora queda disponible un comando en el PATH:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/rubyfunday11.png" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;Si ejecutamos &lt;b&gt;Rails new &amp;lt;name&amp;gt;&lt;/b&gt; se crea un directorio con toda la estructura de una aplicaci&amp;oacute;n Rails:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/rubyfunday12.png" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;Pero vean que me di&amp;oacute; error:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/rubyfunday13.png" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;&amp;iquest;Qu&amp;eacute; pasa? Est&amp;aacute; tratando de compilar algo (supongo que en lenguaje C) del json (1.6.1), adem&amp;aacute;s de crear directorios y archivos. Y en Windows, nos faltan las herramientas de compilaci&amp;oacute;n que espera Rails. El mensaje nos lleva de nuevo a:&lt;/p&gt;
&lt;p&gt;&lt;a title="http://rubyinstaller.org/downloads/" href="http://rubyinstaller.org/downloads/"&gt;http://rubyinstaller.org/downloads/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;donde me descargu&amp;eacute; el DevKit (es un archivo .exe). Atenci&amp;oacute;n, al ejecutarlo tiene que poner el directorio destino. Yo puse &lt;b&gt;c:\Software\DevKit&lt;/b&gt;. Este es el directorio que qued&amp;oacute;:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/rubyfunday14.png" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;Una vez que el ejecutable cre&amp;oacute; ese directorio, hay que seguir las instrucciones de:&lt;/p&gt;
&lt;p&gt;&lt;a title="http://github.com/oneclick/rubyinstaller/wiki/Development-Kit" href="http://github.com/oneclick/rubyinstaller/wiki/Development-Kit"&gt;http://github.com/oneclick/rubyinstaller/wiki/Development-Kit&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;que son:&lt;/p&gt;
&lt;p&gt;- Pasar al directorio de DevKit, en mi caso &lt;b&gt;c:\Software\DevKit&lt;/b&gt;.&lt;/p&gt;
&lt;p&gt;- Ejecutar &lt;b&gt;ruby dk.rb init&lt;/b&gt;. &lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/rubyfunday15.png" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;Esto genera un archivo &lt;b&gt;config.yml&lt;/b&gt; con detecta todos los Ruby que est&amp;aacute;n instalados y fueron detectados por el comando:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/rubyfunday16.png" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;En mi m&amp;aacute;quina detect&amp;oacute; &lt;b&gt;c:\Ruby193&lt;/b&gt;. Pueden editarlo si tienen otros Ruby instalados.&lt;/p&gt;
&lt;p&gt;- Luego hay que ejecutar &lt;b&gt;ruby dk.rb install&lt;/b&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/rubyfunday17.png" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;Ahora s&amp;iacute;, puedo volver al directorio de trabajo (en mi caso &lt;b&gt;c:\Git&lt;/b&gt;). Y ejecutar de nuevo el comando de creaci&amp;oacute;n de nuestra aplicaci&amp;oacute;n:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/rubyfunday18.png" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;No hay problema en que algunos archivos ya existan. Pueden tener alguna pregunta como:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/rubyfunday19.png" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;Contest&amp;eacute; Y (Yes). Al final, queda esta aplicaci&amp;oacute;n Rails:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/rubyfunday20.png" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;Pr&amp;oacute;ximos posts: usando git, lanzando la aplicaci&amp;oacute;n Rails, creando el modelo.&lt;/p&gt;
&lt;p&gt;Nos leemos!&lt;/p&gt;
&lt;p&gt;Angel &amp;ldquo;Java&amp;rdquo; Lopez    &lt;br /&gt;&lt;a href="http://www.ajlopez.com"&gt;http://www.ajlopez.com&lt;/a&gt;     &lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1802444" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/Desarrollo+de+Software/default.aspx">Desarrollo de Software</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Desarrollo+Web/default.aspx">Desarrollo Web</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Ruby/default.aspx">Ruby</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Rails/default.aspx">Rails</category></item><item><title>Mi Día en el Ruby Fun Day (2) Instalando Ruby y Rails</title><link>http://msmvps.com/blogs/lopez/archive/2011/11/12/mi-d-237-a-en-el-ruby-fun-day-2-instalando-ruby-y-rails.aspx</link><pubDate>Sat, 12 Nov 2011 17:10:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1802388</guid><dc:creator>lopez</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1802388</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2011/11/12/mi-d-237-a-en-el-ruby-fun-day-2-instalando-ruby-y-rails.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2011/11/08/mi-d-237-a-en-el-ruby-fun-day-1-la-history-de-stephen-anderson.aspx" target="_blank"&gt;Anterior Post&lt;/a&gt;    &lt;br /&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2011/11/14/mi-d-237-a-en-el-ruby-fun-day-3-creando-una-aplicaci-243-n-rails-3.aspx"&gt;Siguiente Post&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;El domingo pasado estuve en el Ruby Fun Day, asistiendo a la Introducci&amp;oacute;n a Ruby on Rails, el framework de desarrollo web escrito sobre Ruby. &lt;a href="http://msmvps.com/blogs/lopez/archive/2011/11/08/mi-d-237-a-en-el-ruby-fun-day-1-la-history-de-stephen-anderson.aspx" target="_blank"&gt;Stephen Anderson fue el instructor&lt;/a&gt;. Veamos si puedo pasar en limpio y por escrito los temas y ejercicios que hicimos.&lt;/p&gt;
&lt;p&gt;Se recomendaba llegar con una notebook que ya tuviera instalado Ruby. Yo lo tom&amp;eacute; de la p&amp;aacute;gina recomendada por RubyConf Argentina:&lt;/p&gt;
&lt;p&gt;&lt;a title="http://www.ruby-lang.org/en/downloads/" href="http://www.ruby-lang.org/en/downloads/"&gt;http://www.ruby-lang.org/en/downloads/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Yo us&amp;eacute; Windows, as&amp;iacute; que us&amp;eacute; &lt;b&gt;RubyInstaller&lt;/b&gt;:&lt;/p&gt;
&lt;p&gt;&lt;a title="http://rubyinstaller.org/" href="http://rubyinstaller.org/"&gt;http://rubyinstaller.org/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Anderson tambi&amp;eacute;n recomend&amp;oacute;, para la gente que ten&amp;iacute;a Linux, usar &lt;b&gt;RVM&lt;/b&gt; (Ruby Version Manager):&lt;/p&gt;
&lt;p&gt;&lt;a title="https://rvm.beginrescueend.com/rvm/install/" href="https://rvm.beginrescueend.com/rvm/install/"&gt;https://rvm.beginrescueend.com/rvm/install/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;que permite especificar por directorio/proyecto cuales gemas (gems) vamos a usar (creo que se editaba un archivo .rvmrc). Las gemas son paquetes que se instalan localmente, con el comando gem (por ejemplo, el propio Ruby on Rails est&amp;aacute; empaquetado como una gema). Ni bien entramos al directorio configurado, rvm cambia las variables de ambiente (como GEM_HOME) para que apunte a un directorio donde est&amp;aacute;n las gemas del proyecto. Entonces, con RVM podemos armar &amp;ldquo;gem sets&amp;rdquo;, conjuntos de gems que estar&amp;aacute;n activas cuando trabajemos con un proyecto. Esto permite que en un proyecto A estemos trabajando con unas gemas, tal vez con la gema X v 1.2, y en otro proyecto podemos referenciar a otras gemas o a las mismas pero de otra versi&amp;oacute;n. Esto tiene un precio: mayor espacio en disco. Cada gem set guarda las gemas en un directorio propio: por lo que comentaron en el workshop, no establece enlaces simb&amp;oacute;licos, as&amp;iacute; que una gema instalada en en el gemset &amp;ldquo;WebProjects&amp;rdquo; puede estar duplicada en otro gemset &amp;ldquo;CustomerXProjects&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;Para los que trabajamos en Windows, la p&amp;aacute;gina de instalaci&amp;oacute;n recomienda &lt;b&gt;pik&lt;/b&gt;:&lt;/p&gt;
&lt;p&gt;&lt;a title="https://github.com/vertiginous/pik" href="https://github.com/vertiginous/pik"&gt;https://github.com/vertiginous/pik&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Yo no us&amp;eacute; todav&amp;iacute;a, pero espero que llegue la oportunidad de necesitarlo.&lt;/p&gt;
&lt;p&gt;Luego de ejecutar &lt;b&gt;RubyInstaller&lt;/b&gt; (con todas las opciones, como agregar su directorio binario en el PATH), tengo disponibles comandos como:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/rubyfunday01.png" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;que es un int&amp;eacute;rprete interactivo. El instalador me dej&amp;oacute; en el men&amp;uacute; de sistema:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/rubyfunday03.png" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;Les recomiendo el libro de Ruby que queda instalado.&lt;/p&gt;
&lt;p&gt;Uno de los comandos (m&amp;aacute;s importantes) es &lt;b&gt;gem&lt;/b&gt;, con &lt;b&gt;gem list&lt;/b&gt; veo las gemas que quedaron instaladas desde el principio:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/rubyfunday02.png" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;Por ejemplo, &lt;b&gt;rake&lt;/b&gt; es un &amp;ldquo;make&amp;rdquo; para Ruby. Puedo ejecutar rake &amp;ndash;T para ver las tareas que ahora tiene definidas:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/rubyfunday04.png" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;Vean que da error porque necesita un &lt;b&gt;rakefile&lt;/b&gt; en el directorio actual.&lt;/p&gt;
&lt;p&gt;Luego de instalar Ruby, lleg&amp;oacute; el momento de instalar Rails, el framework web m&amp;aacute;s popular de Ruby, y el tema del workshop. Lo instal&amp;eacute; con:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/rubyfunday05.png" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;Ese es un listado parcial. Instala casi treintae gemas, tray&amp;eacute;ndolas de repositorios en l&amp;iacute;nea (as&amp;iacute; que necesitan estar conectados para este comando). Tambi&amp;eacute;n genera dos tipos de documentaci&amp;oacute;n para cada gema: como en general la documentaci&amp;oacute;n est&amp;aacute; en l&amp;iacute;nea, tal vez les convenga no generarla localmente. Pueden agregar los par&amp;aacute;metros &amp;ndash;no-ri &amp;ndash;no-rdoc para que no genere los dos formatos de documentaci&amp;oacute;n asumidos:&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:Consolas;"&gt;gem --no-ri --no-rdoc install rails&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Tambi&amp;eacute;n pueden ponerlo como asumido en gem, ver:&lt;/p&gt;
&lt;p&gt;&lt;a title="http://stackoverflow.com/questions/1381725/how-to-make-no-ri-no-rdoc-default-for-gem-install" href="http://stackoverflow.com/questions/1381725/how-to-make-no-ri-no-rdoc-default-for-gem-install"&gt;http://stackoverflow.com/questions/1381725/how-to-make-no-ri-no-rdoc-default-for-gem-install&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Les recomiendo saltarse la documentaci&amp;oacute;n, porque es la parte que m&amp;aacute;s tarda de la instalaci&amp;oacute;n. Si luego quieren sacar documentaci&amp;oacute;n del disco, es tan simple como borrar los directorios de documentaci&amp;oacute;n de cada gema (m&amp;aacute;s abajo muestro donde quedaron en mi instalaci&amp;oacute;n).&lt;/p&gt;
&lt;p&gt;Rails es bastante &amp;ldquo;grande&amp;rdquo; para instalar, vean otro listado parcial del avance de mi instalaci&amp;oacute;n:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/rubyfunday06.png" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;Vean d&amp;oacute;nde dej&amp;oacute; las gems y la documentaci&amp;oacute;n (mi directorio de instalaci&amp;oacute;n es C:\Ruby193):&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/rubyfunday07.png" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;Pueden conocer la versi&amp;oacute;n de Ruby y de Gem instalada, ejecutando:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/rubyfunday08.png" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;MinGW significa Minimalist GNU for Windows, ver:&lt;/p&gt;
&lt;p&gt;&lt;a title="http://www.mingw.org/" href="http://www.mingw.org/"&gt;http://www.mingw.org/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Vean que con el comando:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/rubyfunday09.png" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;se levanta un servidor local con informaci&amp;oacute;n de las gemas instaladas:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/rubyfunday10.png" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;Noten que Ruby tiene un ecosistema de gemas muy bien armado y activo. Es practicamente &amp;ldquo;imposible&amp;rdquo; trabajar en Ruby sin el comando gem.&lt;/p&gt;
&lt;p&gt;Durante el curso, la instalaci&amp;oacute;n de Rails en mi m&amp;aacute;quina habr&amp;aacute; tardado de 20 a 30 minutos. As&amp;iacute; que tengan paciencia. Estimo que el tiempo baja a un tercio o menos si evitan instalar la documentaci&amp;oacute;n (hay comandos para generarla luego).&lt;/p&gt;
&lt;p&gt;Pr&amp;oacute;ximos posts: creando nuestra primera aplicaci&amp;oacute;n web Rails, usando Git, describiendo modelos, desplegando en Heroku.&lt;/p&gt;
&lt;p&gt;Nos leemos!&lt;/p&gt;
&lt;p&gt;Angel &amp;ldquo;Java&amp;rdquo; Lopez   &lt;br /&gt;&lt;a href="http://www.ajlopez.com"&gt;http://www.ajlopez.com&lt;/a&gt;    &lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1802388" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/Desarrollo+de+Software/default.aspx">Desarrollo de Software</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Desarrollo+Web/default.aspx">Desarrollo Web</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Ruby/default.aspx">Ruby</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Rails/default.aspx">Rails</category></item></channel></rss>