jueves, 18 de septiembre de 2014

45 lineas de Javascript hacen un pianito

El API de Web Audio esta como pidiendo que alguien haga algo con eso, ofrece infinidad de posibilidades, es mas o menos nueva pero posiblemente lo suficiente madura para poder empezar a probar cosas con eso (para mis informacion ver la tabla de compatibilidades)

Por ahora las teclas son Z, X, C, V.. etc... Codigo fuente:
(function() {

    var audio = new window.webkitAudioContext();
    var oscillators = {};

    function createOscillator(freq) {
        var osc = audio.createOscillator();

        osc.frequency.value = freq;
        osc.type = "square";
        osc.connect(audio.destination);
        return osc;
    };

    var frequency = function(notenum) {
        return 293.66 * Math.pow(2, notenum/12);
    };

    var keyCodeToNote = {90: 'C', 88: 'D',  67: 'E', 86: 'F', 66: 'G', 78: 'A', 77: 'B'};
    var noteToNum = {C: 0, D: 2, E: 4, F: 5, G: 7, A: 9, B: 11};
    document.getElementById("pianito").onkeydown = function(e) {
        var osc = oscillators[e.keyCode];
        if (osc) return;

        var note = keyCodeToNote[e.keyCode];
        if (note == undefined) return;
        var noteNum = noteToNum[note];
        var freq = frequency(noteNum);
        var osc = createOscillator(freq);

        oscillators[e.keyCode] = osc;
        osc.start(0);
    };
    document.getElementById("pianito").onkeyup = function(e) {
        var osc = oscillators[e.keyCode];
        if (!osc) return;
        osc.stop(0);
        osc.disconnect(audio.destination);

        oscillators[e.keyCode] = undefined;
    };
})();


Bastante rudimentario, pero es algo para empezar


domingo, 6 de abril de 2014

Quadnet Project


Desde hace un par años tengo la intencion de meterme de lleno a Javascript, las razones de porque se analizan en este post: http://nilclass.blogspot.com.ar/2014/01/vuelta-el-blog.html

Considere que una buena manera de empezar, es con un proyecto "real", o sea que tenga como proposito desarrollar algo que sea utilizado (jugado) por un usuario final.

Podria crear algo nuevo o no, pero lo mas importante para mi es que el desafio sea tecnico: CSS, HTML, WebGL, Social Buttons, backend (o no), etc.... Por eso mismo decidi hacer un remake de un juego que me gustaba mucho, que se llamaba QUADNET

Quadnet


Mas o menos por el 1999, yo pasaba horas y horas jugando a este juego que es muy adictivo http://www.martinmagni.com/1998/12/quadnet-fast-and-furious-arcade-action, este juego lo desarrollo un Sueco (http://www.martinmagni.com) a partir de un concepto muy original, lo desarrollo para que corra en MS-DOS, aunque para ese año se estaba poniendo en voga los juegos que corren en windows, aun DOS era una buena alternativa como plataforma para la cual programar juegos. 

Es un juego original, sencillo, y al mismo tiempo muy bueno justamente por su sencillez. Es el proyecto perfecto como desafio introductorio al desarrollo de juegos en alguna plataforma.

El desarrollo


Como la mayoria de las cosas que hice las tuve que aprender, me plantie resolver solo un problema a la vez, en este orden:

  1. Como y donde hostear el juego: en una pagina de github
  2. Hacer objetos graficos del juego en una version rudimentaria (por ej: los asteriodes eran simples esferas)
  3. Desarrollar la logica basica del juego
  4. Completar el aspecto grafico de los objetos
  5. Efectos de explosiones similar al original
  6. Sonidos
  7. Musica :), tampoco me dedique a crear nada nuevo en este aspecto, pero si re-edite la musica del juego original de 1998
  8. Optimizar las explosiones, porque hasta en un  dual core se laggeaba :(
  9. Menu y pantallas de presentacion del juego, incluyendo instrucciones de como jugarlo
  10. Pantalla de "Leaderboard" que muestra los puntajes mas altos
  11. Botones de redes sociales
  12. Hacer que el Leaderboard sea online

Lecciones Aprendidas


Como ya mencione, el objetivo mas importantes que me plantie con este proyecto es aprender javascript "haciendo algo", y con este primer proyecto si que tuve que aprender varias cosas nuevas

Three.js


Por los visto, es LA libreria JS para hacer graficos 3D con WebGL en el browser, el API provisto por los browsers es apenas la minima necesaria para poder acceder a la funcionalidad (casi un calco de lo que es el API que se usaria en C) por lo que no tienen ninguna clase, patrones, funcionalidades accesorias, recursos (por ej shaders) que si agrega una libreria como three.js. Sin duda es preferible utilizar three.js a programar directamente sobre WebGL, al menos para empezar, y fue el caso con este proyecto.
Para mas informacion, vean los ejemplos de lo que esa libreria esa capaz de hacer de manera bastante sencilla: http://threejs.org/examples/

Promises


Promises es un patron muy util en javascript que se implemento como respuesta al tan temido callback hell, "callback hell" es lo que sucede cuando en javascript, se necesita realizar muchas operaciones asincronicas en secuencia (practicamente todo lo que puede demorar es asi en javascript) y aparentemente la mejor opcion si tenemos que hacer 1,2 y 3, llamemos a 2 en el callback de 1, a 3 en el callback de 2, y asi:

// hago tres request, una atras de otra
$.get('/url1/resource1', function(data1) {
  // hacer cosas con data1
  $.get('/url2/resource2', function(data2) {
    // hacer cosas con data1
    $.get('/url3/resource3', function(data3) {
      // hacer cosas con data3
    });
  });
  
});
Pero en lugar de eso...
$.get('/url1/resource1')
  .then(function(data1){
    // hacer cosas con data1
    return $.get('/url2/resource2');
  })
  .then(function(data2){
    // hacer cosas con data2
    return $.get('/url3/resource3');
  })
  .then(function(data3){
    // hacer cosas con data3
  });
Realmente hay que ejecutar esos request en secuencia?, si el resultado de uno no influye en como hacer los otros, se podria hacer asi para ejecutarlos en paralelo
$.when(
  $.get('/url1/resource1').done(function(data1){
    // hacer cosas con data1
  }),
  $.get('/url2/resource2').done(function(data2){
    // hacer cosas con data2
  }),
  $.get('/url3/resource3').done(function(data3){
    // hacer cosas con data3
  })
);
Pero, "necesito combinar data1, data2 y data3 para hacer algo con los tres". Entonces:
var data1, data2, data3;
$.when(
  $.get('/url1/resource1').done(function(result){
    data1 = result;
  }),
  $.get('/url1/resource2').done(function(result){
    data2 = result;
  }),
  $.get('/url1/resource3').done(function(result){
    data3 = result;
  })
).done(function() {
  // termino de ejecutar las tres peticiones
  // puedo hacer algo con data1, data2 y data3
});

En estos ejemplos utilize deferred, la implementacion de Promises que viene con jQuery, en mi proyecto utilize Promise que es otra alternativa, ambas son muy similares y el usar una u otra depende de la situacion (por ej, si ya estas usando jQuery tenes a mano deferred, pero talvez te interese Promise por el hecho de que implementa un API mas similar a la que aparentemente se estandarizara)


Memory Leaks


El entorno del browser (o node) donde corre javascript se encarga de gestionar la memoria mediante un Garbage Collector, tal como ocurre en Ruby, Python, Java, #NET y muchos otros, sin embargo esto no lo deja exento de problemas relacionados con Memory Leaks

En C o en C++ se debe utilizar la funcion free o la palabra reservada delete siempre para liberar la memoria que ocupa un objeto, en Javascript como ya se menciono esto ocurre automaticamente, pero el riesgo del memory leak ocurre cuando inadvertidamente se crean colecciones muy grandes de referencias a objetos, que nunca seran liberados de la memoria porq el garbage collector los considerada "reachables" 

En C y en C++ la pesadilla de los memory leaks si mitiga con herramientas como Valgrind que detecta elementos en el heap no liberados. 
En Javascript la primer herramienta que tuve a mano es el potente Heap Snapshot de Chrome, creo que el titulo lo dice todo: captura el estado actual del heap con todos sus objetos, y ademas muestra quien tiene referencia a quien, y la razon por la cual el GC no decidio borrarlo (que otros objetos o funciones-scope tienen referencais a el)




Por supuesto que al uso de esta herramienta se complementa las buenas practicas de la gestion de memoria dinamica, en el caso de C++ era asegurarse de borrar cosas en el destructor y usar la palabra new lo menos posible, o al menos encapsular toda esa gestion de memoria en una clase estructura (Arboles, listas, etc...)
En el caso de Javascript por el momento solo conozco una tres cosas (me faltaria averiguar si hay mas)
  • Setear a null las referencias que no se usaran mas, esto nos asegura que esas referencias no van a retener la liberacion de los objetos, no conviene usar delete porque acarrea problemas de performance
  • Evitar los closures innecesarios, ya que cuando se crean los closures estos matienen referencia a los scopes con sus variables y todos los objetos
  • Evitar tener arrays de objetos que crecen constantemente y sin ningun tipo de control


CSS Transitions and Transforms


No puedo creer lo sencillo que es setearlas, y las posibilidades que tiene, para dar un ejemplo, pasen el puntero por esta imagen:



Que paso?, la imagen tiene una class "escalando", entonces con este CSS:
img.escalando:hover {
  transform:scale(5,5);
  -ms-transform:scale(5,5); /* IE 9 */
  -webkit-transform:scale(5,5); /* Opera, Chrome, and Safari */
  transition: all 1s ease-out;
}
Se logra.

  1. Que cuando se pase el puntero por el elemento img, con class escalando, le aplique una transformacion de escalado a 5 veces su tamaño, y 
  2. Que utilice una transition que aplica a todos sus atributos de estilos (incluyendo al width y al height), esta transition en este caso dura un segundo (1s) y la hace con efecto de desaceleracion (ease-out)

Local Storage


Una nueva feature de HTML5, me sirvio para almacenar los highscores, la idea sencillamente es almacenar datos en la maquina donde se esta ejecutando la pagina, seria similar a lo que son las cookies, pero con la diferencia que no expiran y hay un espacio mas amplio (alrededor de 5MB por dominio en Chrome, en otros browsers anda mas o menos por lo mismo)

Se estructura como un hash clave-valor y su uso es tan sencillo como hacer esto:

window.localStorage.setItem("keyname", value)


Firebase (y el no-backend)


Mas tarde, muchos me dijeron o plantearon que seria interesante que la tabla de highscores no sea algo local a la maquina donde corre el juego, que sea algo centralizado para todas las instancias del juego, eso haria que el juego se convierte facilmente en algo competitivo, y casi "social".
De una imagine la solucion clasica: un aplicacion backend desarrollada posiblemente con Ruby con algun framework sencillo como sinatra, o desarrollada con Node.js, talvez hosteada en Heroku con su DB (algo simple, solo una tabla con los puntajes mas altos), y por supuesto el juego mandando los request a ese server

Pero alguien con una problematica similar en un proyecto muy groso para celulares, me recomendo que le de una mirada a Firebase. Que es Firebase?, a grandes rasgos una solucion "generica" de base de datos + backend, con la filosofia del "no-backend", que seria desarrollar apps distribuidas "sin backend" (bueno, en realidad usaria un servicio como Firebase, ellos cumplirian el rol de "backend") pero el punto es que con eso pude desarrollar el Leaderboard centralizado sin tener que preocuparme por hostear absolutamente nada ni programar algo server side, si quieren conocer mas detalles les recomendaria que se pasen por el sitio de Firebase: https://www.firebase.com/

Links


El juego hosteado en github: http://tario.github.io/quadnet/
Pagina del juego, con el codigo fuente: https://github.com/tario/quadnet
Sitio oficial de three.js: http://threejs.org/
Juego original al cual emula: http://www.martinmagnusson.com/games/quadnet/
Mas informacion de localStorage: http://www.w3schools.com/html/html5_webstorage.asp
Sitio oficial de Firebase: https://www.firebase.com/


sábado, 18 de enero de 2014

Vuelta el blog

Por diversas razones, talvez mas por dejadez que otra cosa he dejado gradualmente de bloggear hasta que en el 2012 para del todo, muchas cosas cambiaron desde la ultima vez que bloggie, cuando comente mis impresiones de la rubyconf 2012, y ya estamos en el 2014, y se hizo la rubyconf 2013 (a la que le dedicare un justo post)
Otra cosa que cambio, al menos en mi caso, la relevancia que le doy a la parte del desarrollo client-side, digamos que ya estamos bastante lejos de las epocas en que todo se hacia "en el server" y el browser actuaba como un simple renderizador de html. 
En la ultima decada, pero mas que nada en el ultimo par de años las cosas cambiaron mucho con respecto a lo que los browsers son capaces de hacer, de a poco se fueron agregando capacidades que antes solo se podian agregar a la aplicacion por medio de plugins, o directamente haciendo una app tradicional, por ej: WebRTC que permite desarrollar apps de comunicacion (como los softphones) 100% en Javascript, WebGL para aceleracion grafica y un largo etc...

Una muestra de lo que digo, es "Epic Citadel" para el caso de WebGL, y el hangout de google que utiliza lo de webrtc (creo)

Ruby sigue siendo un lenguaje potente y cada vez se extiende mas, pero el ecosistema y comunidad de ruby esta bastante orientado al desarrollo rapido de backend (casi ninguna tecnologia lo supera en eso), como excasas excepciones existen algunas gemas, algunas medio experimentales que ayudan para usar ruby client-side, solo enumero algunas:

  • Shoesrb: framework orientado a desarrollar interfaces de ventanas, para apps "tradicionales" (o sea, no web) con un azucar sintactico bastante sencillo, al estilo los frameworks webs mas conocidos como sinatra
  • Rubygame: Libreria multimedia que ayuda al desarrollo de juegos en ruby
  • OpalrbTranspiler que convierte codigo Ruby a Javascript para que pueda ser ejecutado en el browser

Y todas son excelentes, pero sufren el problema de ser complejos y aparatosos de instalar, no para el caso del desarrollador que esta canchero con eso, sino mas que nada para el usuario final, recuerden que al ser ruby un lenguaje interpretado, como minimo se debe instalar el interprete del lenguaje, y en el caso de usar librerias como shoesrb y rubygame, se tienen que instalar las dependencias, creo que gtk en el caso de shoes y sdl en el caso de rubygame

Opalrb como concepto se ve muy interesante, pero lamentablemente los browsers no dan soporte realmente bueno para debuggear lenguajes que no sean javascript, se que existe lo de source maps, pero lei por ahi que desarrollar con algo que no sea javascript para el browser sigue siendo complicado igual

En fin, llegue a la conclusion que Javascript es un lenguaje que hay que conocer si o si, al menos si tu intencion es hacer aplicaciones que sean sencillas de instalar y usar para el usuario final, por eso empece a hacer algunas pruebas, y con un tema que me gusta, los graficos 3D:

Para empezar una demo basica con figuras geometricas, muy elemental, pero si miran en el codigo fuente se puede ver hypercomentado, muy util para ir aprendiendo Javascript (como yo en el momento de escribir esas demos)
http://tario.github.io/threejs_demos/

Despues, un proyecto apuntando a algo, no esta terminado, mas tarde le dedicare un merecido post
http://tario.github.io/quadnet




sábado, 20 de octubre de 2012

Rubyconf 2012

Update: ya estan disponibles todos los videos de la conferencia aca

Este fin de semana fui a la rubyconf que se organizo en la Argentina, pais donde vivo en el cual fue la segunda vez consecutiva que se organiza un evento de tal magnitud con Ruby como tema central.
En la foto principal de articulo pueden ver el pin rojo de la RubyConf 2011 y el nuevo pin amarillo de RubyConf 2012.

Como lo plantearon los organizadores del evento en un principio, esperaba la aparición de figuras relacionadas con el desarrollo del lenguaje provenientes de Japon al igual que el año pasado vinieron a presentar Yutaka Hara, Koichiro Eto y Narihiro Nakamura (pueden ver sus charlas y otras mas aca), por lo visto este año no fue posible pero mas alla de eso considero que el nivel de las charlas y la organiacion mejoraron en comparación al año pasado y no faltaron las grandes personalidades del mundo ruby local, paises vecinos y varios paises lejanos del "otro lado del charco", con visitar la pagina se puede saber quienes son

Todas las charlas estuvieron buenisimas, doy mis comentarios de las charlas que mas me gustaron
Update: tambien incluyo los videos de las mismas

Ship it: Staying Lean at LivingSocial


Andy Atkinson de livingsocial nos explica como aplican Lean a la hora de evaluar la incorporación de nuevas features. Una de las cosas mas interesantes que conto es que en lugar de desarrollar la feature completa y largarla, hacen "pedacitos de feature" o incluso solo un "preview" para que todos o un grupo seleccionado de usuarios envien feedback, si el feedback es bueno siguen adelante y van avanzando en el desarrollo de esa funcionalidad en caso contrario la dejan de lado.
Conto como ejemplo el caso de una funcionalidad hypercompleja de implementar (ahora no me acuerdo que era) que a los usuarios no les importaba y una cosa tan sencilla de implementar como un "boton de express checkout" tuvo mucho exito y les genero un monton de ganancia.

The web of tomorrow

Excelente charla de @cuerbot, con una buena presentación y graficas vintage acordes transmite un mensaje de Javascript, P2P y libertarismo digital. Basicamente explico con ejemplos puntuales como las aplicaciones en javascript usan WebRTC pueden comunicar directamente browser con browser sin servidor de por medio a excepcion de una intervencion minima al principio de la conexion similar a como lo hacen hoy VoIP y las redes P2P de intercambio de archivos. Las claras consecuencias de esto segun mi forma de ver:

  • Streaming de audio y/o video entre browsers sin servers como intermediarios
  • Drastica baja de requisitos de performance en el lado del server al trasladar casi la totalidad de la carga de la aplicacion a los browsers
  • Descentralizacion de las comunicaciones mitigando la censura en la web
  • Solo la imaginacion es el limite....
Otra cosa interesante de esta charla es que fue la única en mostrar puro codigo javascript, constituye un puesto de avanzada de invasion de javascript en el espacio de ruby, pero le doy la bienvenida

Aca los slides: https://speakerdeck.com/u/elcuervo/p/the-web-of-tomorrow

Rails 4 en 30 minutos


Introducción a Rails 4 que se liberara en pocas semanas la versión estable, fueron asombrosas las cosas que mostro como por ejemplo las queues (antes habia que recurrir a una gema adicional para eso) y ActionController::Live


Comida

Merienda con brownies de chocolate explosivo, medialunas, budines, sangunches, almuerzo con sanguches, metasushi, comida vegetariana y desayuno también.
La comida es una de las cosas en la que los organizadores se superaron












REST in peace

No se preocupen, todavia REST no murio (de hecho falta muucho para eso). Martin Salias ataca de nuevo y esta vez nos explica como hay que desarrollar interfaces REST como es debido.
Principales lecciones que me quedaron:

  • Usar verbos y status codes que corresponden (ej: no usar un verbo GET para borrar algo)
  • No devolver identificadores de obetos relacionados en el json/xml, porque el cliente tiene que construir las URLs (y estas podrian cambiar con el versionado, etc...)
  • Sinatra parece ser mejor que rails para hacer algo simple como esto :D


Rapid Prototyping with Sass, Compass and Nanoc

No me acuerdo muchos detalles ahora, pero básicamente explicaron el toolkit de herramientas que usan para prototipar interfaces usando lo que ya se sabe de lenguajes markup de ruby, una de las que mas me intereso fue middleman,  un server de paginas estáticas muy util para prototipar cosas sin necesidad de tener que lidiar con alguna complejidad innecesaria de un framework web

Infrastructure as Ruby code



Explica como Ruby es extremadamente util  (mucho mas de lo que yo me imaginaba) al servicio de un Sysadmin, herramientas como vagrant y chef para administrar/deployar múltiples servidores, ya no en la forma "tradicional" de tener una maquina física que dure mucho tiempo, sino de una manera adaptada a la era del cloud computing en la cual los servidores son "efímeros" y el scripteo, la automatización  la escalabilidad horizontal y la posibilidad de repetir fácilmente las configuraciones se vuelve una herramienta crucial para aprovechar bien los recursos que hay ahora.

Slides: https://speakerdeck.com/u/abecciu/p/infrastructure-as-ruby-code

domingo, 27 de mayo de 2012

Fin de semana de lisp

El fin de semana pasado fui a la jsconf, y a partir de una charla de ajlopez (Implementando lenguajes de programacion en javascript) y una incidencia de lenguajes formales (una materia que estoy cursando ahora en la facultad) me plantee el objetivo de hacer el interprete de lisp en ruby

Lo que no estaba tan al tanto, es que como lisp es una influencia importante en muchos lenguajes actualmente vigentes (principalmente lenguajes dinamicos) como javascript, python y por supueso ruby, tiene caracteristicas que permiten hacer una "conversion" mas o menos legitima


Y es que, como explico ajlopez en su presentacion, muchos interpretes de X lenguaje hechos en otro lenguaje Y podrian utilizar la generacion de codigo, que es la tecnica que me llego a parecer mejor cuando estaba escribiendo las primeras lineas de dslisprb

Entonces...

Atomos numericos de lisp son Fixnum, Float, Bignum, o sea objetos numericos de ruby
Las listas de lisp son obviamente Arrays de ruby 
Los lambdas de lisp son lambdas de ruby, y por lo tanto...
Las variables de lisp son variables de ruby
Las funciones de lisp, no son mas que variables con un lambda asignado, por lo tanto son lambdas de ruby (ejemplo: la funcion car que se define como un lambda)

Para ejecutar el codigo lisp, este se parsea a un ast, el ast se convierte a ruby, y finalmente se evalua. Las variables lisp se representan en variables de ruby y todo se ejecuta en el mismo binding para cada instancia de DsLisp (de esta manera, si se asigna una variable en una llamada a evaluate esta sera accesible en las sucesivas llamadas)

Instalar y usar

gem install dslisprb


Para usarlo seguir las instrucciones en el README, igualmente lo hice lo mas intuitivo que me salio para Ruby 1.9, aunque no podria descartar que funcione tambien en el viejo ruby

Al final lo unico raro de este proyecto es que no implica absolutamente nada de javascript, ese lenguaje me resulta muy interesante, pero para otras cosas (webgl, jueguitos, UI, :D )

domingo, 1 de abril de 2012

Menos precision por favor

Estoy cursando numerico en fiuba y se dio la necesidad de probar varios algoritmos en distintos grados de precision (el ejemplo mas claro de esto, es el tipo de datos double y float de C)
, como todo rubyfan decidi hacerlo en ruby, pero ruby solo tiene un tipo de dato de punto flotante, llamado Float, que wrappea el double nativo de C

El truco, como en otros lenguajes con solo una precision de punto flotante, es emularlo; es decir, truncarlo a la precision deseada despues de cada operacion. Ruby tiene soluciones interesantes para hacer este tipo de cosas.

El decorator


En un principio, usamos un patron llamado decorator, con la idea de modificar el comportamiento del float:

Nuestro FloatDecorator repite cada operacion en el objeto "decorado", pero al retornar el resultado lo trunca y lo decora tambien asi mantiene el comportamiento

Asi, la raiz cuadrada de dos 2**0.5 da 1.41 y no 1.4142135623730951






La manera mas rubyway de implementar un decorator es usando method_missing En este caso se implementaria asi:
class FloatPrecisionDecorator
  def initialize(inner, factor)
    @factor = factor
    @inner = inner.to_f
  end

  def method_missing(m,*x)
    # todas las operaciones sobre el numero se ejecutan sobre el float verdadero
    # y se obtiene el verdadero resultado con precision completa del Float original
    verdadero_resultado = @inner.send(m,*x)
    # se reduce la precision, multiplicando por el factor, redondeando y volviendo a dividir
    reduced = (verdadero_resultado.to_f * @factor).round.to_f / @factor
    FloatPrecisionDecorator.new(reduced, @factor)
  end
end

# esto da un FloatPrecisionDecorator con un 1.41, adentro, no un 1.4142135623730951
p FloatPrecisionDecorator.new(2,100)**0.5

Inspect


Pero cuando se hace el print por salida estandar, aparece algo asi:

#..floatprecisiondecorator:0x8cd63f8 factor="10," inner="1.4"...

¿ No seria mejor que simplemente mostrara el 1.41 ? Para eso hay que sobrecargar el metodo inspect

class FloatPrecisionDecorator
  def inspect
    # para que llame al inspect del float decorado
    @inner.inspect
  end
end

# ahora si va a mostra simplemente 1.41
p FloatPrecisionDecorator.new(2,100)**0.5

Numeric


Es mejor si se puede hacer asi:


4.0.to_reduced_precision(:decimals => 2)

4.0.to_rp(:decimals => 2)

Para eso lo mejor es agregarle el metodo a la clase numeric:

class Numeric
  def self.reduce_precision(number, factor)
    (number.to_f * factor).round.to_f / factor
  end

  def to_single_precision(options)
    unless options[:factor]
      options[:factor] = (options[:base]||10) ** (options[:decimals]||10)
    end

    factor = options[:factor]

    FloatPrecisionDecorator.new(Numeric.reduce_precision(to_f, factor), factor)
  end
end

Coerce



Puede surgir que se tenga que sumar un numero de precision reducida a un float, pero el metodo + de la clase Float de ruby no tiene forma de saber como sumar el numero que implementamos nosotros. Esos casos ruby lo contempla con el metodo coerce, que habilita conmutar los numeros en una operacion matematica, asi:
class FloatPrecisionDecorator
  def coerce(other)
    return self, other
  end
end

inifinite?, nan? y demas


Si se hace a nuestro numero


p 2.to_sp(:decimals => 10).infinite?


Va a devolver 0.0, cuando se supone que el metodo inifnite debe devolver true o false, esto ocurre porque inifnite? tambien llama a method_missing y este trata de truncar y wrappear lo que sea, lo mejor en estos casos es evitar modificar objetos que no sean numeros. Habra que modificar method_missing:

class FloatPrecisionDecorator
  def method_missing(m,*x)
    # todas las operaciones sobre el numero se ejecutan sobre el float verdadero
    # y se obtiene el verdadero resultado con precision completa del Float original
    verdadero_resultado = @inner.send(m,*x)

    # si es numeric, truncar y wrappear
    if Numeric === verdadero_resultado
      # se reduce la precision, multiplicando por el factor, redondeando y volviendo a dividir
      reduced = (verdadero_resultado.to_f * @factor).round.to_f / @factor
      FloatPrecisionDecorator.new(reduced, @factor)
    else
      # si no, devolve el resultado como es
      verdadero_resultado
    end
  end
end

Codigo completo





class Numeric
  def self.reduce_precision(number, factor)
    (number.to_f * factor).round.to_f / factor
  end

  def to_single_precision(options)
    unless options[:factor]
      options[:factor] = (options[:base]||10) ** (options[:decimals]||10)
    end

    factor = options[:factor]

    FloatPrecisionDecorator.new(Numeric.reduce_precision(to_f, factor), factor)
  end
end

class FloatPrecisionDecorator
  def initialize(inner, factor)
    @factor = factor
    @inner = inner.to_f
  end

  def method_missing(m,*x)
    # todas las operaciones sobre el numero se ejecutan sobre el float verdadero
    # y se obtiene el verdadero resultado con precision completa del Float original
    verdadero_resultado = @inner.send(m,*x)

    # si es numeric, truncar y wrappear
    if Numeric === verdadero_resultado
      # se reduce la precision, multiplicando por el factor, redondeando y volviendo a dividir
      reduced = (verdadero_resultado.to_f * @factor).round.to_f / @factor
      FloatPrecisionDecorator.new(reduced, @factor)
    else
      # si no, devolve el resultado como es
      verdadero_resultado
    end
  end

  def coerce(other)
    return self, other
  end

  def inspect
    # para que llame al inspect del float decorado
    @inner.inspect
  end
end

p FloatPrecisionDecorator.new(2,10).infinite?



jueves, 22 de marzo de 2012

TIrate que? tirate un AJAX

Por algo se empieza...

$.ajax({ url: '/meme', statusCode: {404: function(){alert('not found');} } }).done(function(){alert('hello');});

lunes, 2 de enero de 2012

No mas excusas para no testear con picotest

Picotest es una gem pensada principalmente para testear pequeños metodos, como helpers, funciones de calculo, etc...
Apenas se libero una primera version 0.0.1 de prueba para mostrar la idea, la cual consiste en evitar el "no vale la pena testear esto" cuando estamos frente a metodos o funciones que tienen un monton de casos pero testearlos supondria escribir mucha mas cantidad de lineas de codigo de lo que implicaria la propia funcionalidad que se testea
La solucion a esto en picotest es ofrecer un DSL que permita escribir una gran cantidad de casos de prueba en una o por lo menos muy pocas lineas. Por ejemplo:

require "picotest"

suite(1 => 1, 4 => 2, 9 => 3, 16 => 4).test(Math.method(:sqrt))

Tambien tiene sintaxis especifica para hacer oracle testing y mocking muy sencillo (seguir los enlaces para mas informacion)

Enlaces

martes, 27 de diciembre de 2011

The Ruby Game


Es un site que tira acertijos o problemas ruby en los que todos pueden participar enviando el codigo y ves los resultados al instante, lo copado es que podes ver un ranking de las soluciones que todos enviaron y aprender cosas interesantes de la sintaxis de ruby

Let's the game begins!

jueves, 8 de diciembre de 2011

Git para usuarios de Subversion

O mejor dicho:
Git NO es para usuarios de Subversion

Ir de svn a git, no puede ser:
  • Siendo usuario SVN, leer guia "Git para usuarios de Subversion"
  • Siendo usuario SVN, Usar git traduciendo los comandos que ejecutarias si usaras svn (epic fail),
  • Encontraran esa experiencia fea mientras sacan en conclusión que git posee una complejidad innecesaria y es muy difícil de usarlo
"Para un usuario de svn siempre sera mas facil usar svn que git"

Par ir de svn a git, es mejor seguir estos pasos:
  • Siendo usuario SVN, leer guia "Como volverse un usuario de git"
  • Siendo usuario git, Usar git de manera natural
Asi git se usaria mejor, pero quedan dos problemas:
  • "Para un usuario de git siempre sera mas facil usar git que svn" , es decir, que una vez acostumbrado a git usar svn se vuelve complicado.
  • Y mas importante, cambiar de el svn mindset al git mindset no es para nada algo trivial

Si se sigue insistiendo con git, como una mera variante de svn, esto es lo q podria pasar (lo mas comun):
  • Siendo usuario SVN, leer guia "Git para usuarios de Subversion"
  • Pasar meses de agonia mientras se maldice a git, a Linus Torvalds y al manager/PL/co-equiper/profesor que te hizo usarlo ya que es muy complicado al pedo ("¡lo unico que quiero hacer es commitear!", "¡mis cambios desaparecieron!", "¡el merge fallo y perdi todo!", y asi...)
  • Librarse de git de alguna manera y volver al placido y reconfortante svn (o cvs :( )
O si no, esto es mas raro que pase:
  • Siendo usuario SVN, leer guia "Git para usuarios de Subversion"
  • Pasar meses de agonia mientras se maldice a git, a Linus Torvalds y al manager/PL/co-equiper/profesor que te hizo usarlo ya que es muy complicado al pedo ("¡lo unico que quiero hacer es commitear!", "¡mis cambios desaparecieron!", "¡el merge fallo y perdi todo!", y asi...)
  • Aprender como funciona y hacer "cosas que con svn no hacia", explotar sus ventajas
  • Volverse "usuario git" al "entender como funciona" a costa de todo el sufrimiento previo
  • Optar por git como control de versiones preferido en todo al punto de creer que usar subversion en realidad un obstáculo
De todo esto se concluye que es muy difícil que alguna tabla de equivalencia de comandos o "mini-tutorial" sirva para que un usuario que esta cómodo con svn pueda trabajar igual de cómodo y feliz con git, o por lo menos que valga la pena el cambio, para eso un usuario debe volverse "usuario de git" antes de usarlo y/o en primeras etapas del uso de la herramienta.

Que es ser un usuario de svn y que es ser un usuario de git (mindsets)

En esta seccion me voy a referir a un "usuario de svn" a alguien que usa svn desde hace mucho tiempo, y que esta comodo y feliz con la herramienta ya que tiene ese "mindset". Lo mismo para un "usuario de git".

No obstante, la característica mas importante a analizar no es la herramienta, sino la manera de pensar las cosas, los conceptos y en ultima instancia como resuelve las situaciones del dia a dia con su herramienta favorita. Como esto no es "git evangelism", y el foco es estudiar como pasar de svn a git, sere lo mas objetivo posible

Lo mas sencillo sera mostrar la siguiente tabla:

Problema o conceptoUsuario de svnUsuario de git
Tengo código que quiero guardar,
pero "no esta listo" para integrarlo
al trunk por lo que no quiero
commitearlo ¿Que hago?
"Facil: tengo tres opciones:
  • copio el codigo, y lo pego en un notepad,
  • copio en el mismo archivo pero comentado
  • No hago nada, porque se que puedo volver atrás con ctrl+Z
  • crear un branch, pero preferiria que no"
"Facil: puedo commitear ya que ese commit es local, o si no también puedo crear un branch"

Estoy trabajando en una feature nueva que todavia no commitie, y alguien me pide que resuelva un bug ¿que hago?
  • GTFO, esperar hasta que termine la feature y haga el commit
  • Hacer checkout del mismo repo en otro directorio, arreglarlo ahi y commitearlo
  • Copiar el codigo a otro directorio, revertir la WC, arreglarlo ahi y copiarlo
  • Guardo un "stash", arreglo el bug, commit, push. restauro el stash
  • Hago un branch

Tengo una funcionalidad a medio hacer sin commitear y me tengo que ir a mi casa, mis compañeros se quedan y podrian continuarla
  • No commiteo, solo yo sigo mi trabajo mañana
  • commiteo aunque el trunk quede inestable
  • Les doy mi computadora
  • Hago un zip con el codigo y se los mando
  • Me quedo hasta que pueda commitear algo bueno
  • Commiteo (es local) y despues pusheo a un branch asi los demas pueden seguir trabajando en el
Dos o mas integrantes del equipo colaboraran en el desarrollo de un nueva feature, que tardara un mes
  • Ahora si se justifica crear un branch
  • Pair-Programming y commitear cuando termine (no conviene)
  • Fragmentar en features mas pequeñas y commitear todos los días siempre y cuando "no rompan nada"
  • Definitivamente hay que crear un branch
Dos o mas integrantes del equipo colaboraran en el desarrollo de un nueva feature, que se completara en el diaPair-Programming y commit cuando se completeBranch
Commit"Es la esencia de esto, hay que hacer update antes del commit para integrar los cambios del servidor""Puedo commitear cuando quiera independientemente de que ocurra en el 'servidor'"
Branch"Creare branches solo cuando sea estrictamente necesario (por ej: features que tardaran mucho mucho tiempo) o lo indique la gente de SCM""Lo mas importante es saber manipular branches, porque aparecen todo el tiempo si se trabaja de manera distribuida"
Merge"Pasa automatico cuando hago update pero hacer un merge manual es un quilombo y tarda, por eso no convienen los branches""Pasa automaticamente cada vez que hago un pull y hacerlo manual es trivial y rapido"
Historia"La historia se almacena en una secuencia de changesets, por eso cada revision tiene un numero, eso lo hace sencillo""La historia se almacena como un DAG (Arbol) de commits, entender eso es importante para comprender los branches"


El usuario de svn usa los sencillos comandos provistos por svn y varias herramientas mas como editores, IDE, compresores, mail, etc... para resolver los problemas del dia a dia, mientras que el usuario de git para resolver los mismos problemas diarios usa solamente git, que para ser justos, git en realidad es un filesystem mas un set muy extenso de herramientas sencillas, pero git como conjunto de herramientas es complejo, quiere ser lo suficientemente complejo y sofisticado para cubrir todas las necesidades y que no sean necesarios ni notepads, ni código com
entado, ni mails, ni ctrl-Z para manejar versiones de código.

Un usuario de git estara pensando todo el tiempo que hace control de versiones en branches, para el es fundamental saber como manipular branches (crear, mergear, etc...) ya que sabe que los branches se crean todo el tiempo por trabajar de manera distribuida. Asumen el concepto de que es literalmente imposible trabajar sin branches en un equipo de desarrollo y por lo tanto no buscaran el imposible de "evitar branch a toda costa" sino solamente se dedicaran a controlar los branches que surgen para que no diverjan demasiado.
Consideran que todas las versiones son parte de un arbol que muestra la divergencia.

Un usuario de svn se enfoca principalmente en la "linea principal" y pensara en branches solo si surgen ciertas situaciones puntuales como por ej una feature que tardara demasiado tiempo (que en general es mejor evitar) o una version alterna del producto a medida. Asumen que la creación de branches siempre conlleva un overhead que en muchos casos solo sirven para complicar mas las cosas, muchos usuarios svn concuerdan en que si un branch va a durar mucho tiempo (digamos semanas) y se justifica podria aceptarse si el beneficio que se presume traera el branch supera ese overhead. Asi mismo cuando un branch se extiende en el tiempo y diverge mucho la integracion a la linea principal se vuelve mas complicada por lo que la integracion de esos "branches mounstruosos" es algo que no se busca (true story).
No consideran que la diferencia entre su working copy y lo que hay en el servidor sea un branch por que commitear y updatear es mucho mas facil que manipular branches.
Ven las versiones del repositorio como algo lineal

¿ Que pasa cuando hay que usar una herramienta "diferente" ?

Si un usuario svn, pasa a usar git con la consigna "reemplazo svn con git en mi set de herramientas", se encontrara que la complejidad de git, que es mayor que la de svn, sumada a la complejidad de las herramientas que esta acostumbrado a usar (bloc de notas, mails, etc...) se convertira en una molestia y no podría trabajar bien. Mientras que un usuario habituado a git, usa git para una mayor cantidad de cosas aprovechando al maximo posible las posibilidades de la herramienta (que son la cara buena de esas complejidades) y no permitiendo que surja necesidad de usar algo adicional, asi es como muchos se maravillan con git mientras otros no entienden porque si git es tan complicado.
Por ejemplo, a un usuario svn generalmente no se le ocurriría crear branches de corta duracion, porque tiene la idea de que son complicados y no valen la pena, ahi habria una ventaja que no se aprovecharía (mientras que lidear con muchas de las cosas complicadas esta implícito en el uso dirio). A alguien habituado con svn tambien le causaria mucha confusion el hacer un git pull y que el merge automatico no funcione, que se haya arrepentido o lo que sea ya que lo que hay en git no puede ser visualizado con un modelo lineal.

También es complicado para un usuario de git trabajar con svn, ya que tiene la costumbre de manejar el versionado de código solamente con una herramienta, se encontrara con que en svn los branches cortos no valen la pena y que hay muchas herramientas que faltan en comparación con git al que esta habituado y como esta acostumbrado a usar git todo el tiempo casi no conoce de herramientas "extras" y trabajar con svn le seria dificil.

Por eso el philosoraptor de la imagen se pregunta porque no existen manuales de svn para usuarios de git (mas bien seria manuales de las herramientas adicionales que hacen falta para complementar svn) si existen manuales de git para usuarios de svn.

Conclusión, como pasar de svn a git
  • Comprender que con git las cosas se hacen diferente, que hacerlas "a la vieja usanza" es mas complicado que con la herramienta de siempre
  • Abordar git de cara a las ventajas (ej: branching, merging, distribuido, forks, staging area, versionado local, etc...)
  • Cambiar la manera de hacer las cosas, para aprovechar funcionalidades de git (no pensar, tal funcionalidad no la uso porque así no hago las cosas, cambiar la manera de hacer las cosas)
  • Pensar "out of the box", estar listo para cambiar las estructuras de pensamiento mas elementales
  • Al enfrentarse a complejidades adicionales que no había en svn, buscar comprender porque es asi, como eso se relaciona con ventajas de la herramienta y como aprovechar esas ventajas
  • Ver las versiones como un arbol y manipularlas de esa forma. NO tratar de que las cosas funcionen como en svn (por ej: no pretender que git pull funcione como svn update porque son cosas diferentes)
  • Invertir tiempo, mucha gente que usa git dice que lo vale. No existe una manera rápida de aprender git pero el aprenderlo vale la pena

Links

Libro ProGit: http://progit.org/
Generador de memes: http://memegenerator.net/


miércoles, 30 de noviembre de 2011

¿Que version de ruby esta seleccionada con RVM?

RVM

RVM es una herramienta impresionante que permite entre muchas otras cosas switchear de versiones de ruby o gemsets con simples comandos ahorrandonos lo que seria un "configuration hell" cada vez que querriamos cambiar la version de ruby (no se puede andar instalando y desinstalando ruby todos los dias)

El que hace un uso intensivo de RVM con múltiples versiones de ruby/gemsets sabra que averiguar la version@gemset activada en un momento dado requiere correr el comndo rvm current, esto podria ser tedioso si se abren multiples tabs y se quiere saber en un vistazo cual es la version de ruby activada y en primera instancia se puede recurrir a cambiar los titulos de los tabs, pero hay otra cosa adicional que se puede hacer

Poner la version de ruby en el prompt

Cambiar el COMMAND_PROMPT en .bashrc o .bash_profile para que muestre en todo momento la version de ruby activada (ver screenshot), incluso se pueden usar colores y poner lo que sea, aca va un ejemplo de la linea que yo agregue al final de mi .bashrc para que el prompt salga como en la imagen:
PROMPT_COMMAND="echo -n -e '\033[1;31m'\$(rvm current) '\033[0;37m'-\ "

Y de aca puede haber un montón de derivaciones, como por ej poner ruby -v en lugar de rvm current o incluso algunos lo usan para mostrar a que host están conectados por ssh

Actualizacion

Una versión mejorada del comando podría ser agregar algún texto diciendo que es rvm al principio y al final en lugar de poner un comando ANSI para retornar al color gris claro específicamente, usar el color "default" que es el color del texto que sale en la terminal (que esta sujeto a la configuración de la terminal y no necesariamente sera gris claro)

PROMPT_COMMAND="echo -n -e '\033[1;31m'rvm: \$(rvm current) '\033[0m'-\ "

martes, 29 de noviembre de 2011

¿RVM + bundler es un problema? NO (Solucion)

Estoy armando un entorno para desarrollo con rails, y rvm... el como instalar rvm se puede ver en un montón de sitios, empezando por el sitio oficial http://beginrescueend.com/rvm/install/

En resumen, con RVM instalado, tiro esta secuencia de comando
el primero para instalar ruby 1.9.2:

sudo rvm install 1.9.2

Despues, si todo salio bien, hay que switchear a esa version de ruby

rvm use 1.9.2

Instalar la gem rails

gem install rails
Hasta ahi todo bien, pero al intentar generar un aplicacion con rails asi:
rails new testapp
Algo no funciona...

El Problema

Veran que bundle se cuelga "indefinidame
nte" y mientras ruby podria llevarse una porción apreciable de CPU (yo por mi parte espere varios minutos y lo único que obtuve fue perder un núcleo durante ese tiempo y el comando no se completo). Si bien en muchos lugares se explica que esperando un rato largo (10 o 15 minutos) el comando se completa, no es muy tolerable para lo que es el "desarrollo rapido" con RoR.

La Solucion

Buscando por la web, me encontré con este articulo, que explica cual es el problema y da una posible solución (que al menos funciono en mi caso). Básicamente explica que el problema tiene que ver con rubygems, no con bundler.
Lo que hay que hacer es asegurarse de que el cache de gems esta generado, esto se hace corriendo el comando bundle pack, como dice la explicación que extraje de la pagina:

WHAT YOU CAN DO

So it’s still slow. My general advice is to:

  • Check in your vendor/cache directory with your .gem files. If bundle install doesn’t make one, force it with bundle pack.
  • On new installs, CI runs, and deploys, use bundle --local which will attempt to resolve using only vendor/cache
  • Lock down to specific versions (or use the twiddle-wakka) in your Gemfile
Y despues deberia tardar mucho menos en ejecutarse

Workaround

Si por casualidad la solución que les di no funciona pueden aplicar el workaround de crear la aplicación con rails usando la opcion --skip-bundle:

Recuerden que esto causa que las gems básicas de la aplicación no se instalen, por lo que tendrán que instalarlas a mano, para eso hay que ver el archivo Gemfile que esta en el directorio raíz de la aplicacion recién creada e instalar las gemas que figuran ahí con el comando gem.

Y después si usan gemas nuevas que no se especifican por default no olviden agregarlas al Gemfile igual ya que es muy útil por si quieren deployar la app a heroku después o simplemente para que las dependencias estén explicitas. Recuerden que después se puede correr el comando "bundle install" a mano en cualquier momento.

Links

Pagina oficial de RVM: http://beginrescueend.com/rvm/
Explicación de como instalar RVM: http://beginrescueend.com/rvm/install/


viernes, 11 de noviembre de 2011

Rubyconf Argentina 2011

No podía dejar de ir a este evento, no voy a contar todo lo que vi porque el post se volveria demasiado extenso, pero voy a incluir las cosas que mas me impactaron.

Ruby Fun Day

Asi llamaron a la previa que organizaron para dos dias antes de evento. Estuvo muy bien pensado y realmente cumplio lo que decia el titulo Ruby-Fun-Day, en un principio no estaba seguro de ir pero mas tarde me di cuenta de que si no hubiera ido me hubiera arrepentido.

El RubyFunDay lo organizaron para los que querian iniciarse en el mundo de ruby y no anden tan desorientados en las charlas (el plato fuerte) pero para los que tienen cancha también estuvo muy bueno porque dio la oportunidad para conocer gente copada, actualizarse y por ahí otras actividades relativas a agile.

Ese dia aproveche la jornada para aprender de rails y heroku que los tenia un poco olvidados en un taller dictado por @bendycode (Stephen Anderson).

Vean el sitio de tryruby recargado con dibujitos del libro Poignant Guide de Why, es impresionante y una forma muy copada de aprender el lenguaje ruby

Ruby, Ruby, Ruby, Ruby, POO OO OO, la cancion de ruby

Desde el martes, el primer dia de la conferencia, escuche la canción. La deje de ringtone en mi telefono, es muy pegadiza:



El presente de ruby es 1.9

Yutaka Hara dio la charla llamada "Pasado, Presente y Futuro de Ruby", básicamente la lección que mas me quedo es que hay que migrar todo a ruby 1.9, porque ruby 1.8 es el pasado, basta hacer unos simples benchmarks para ver que ruby 1.9 es mucho mas rápido que su antecesor sin contar otras mejoras como ligeros improvements en la sintaxis del lenguaje, inclusión "out-of-the-box" de rubygems y un sin numero de otras cosas (talvez en la pagina oficial de ruby se encontrara información detallada)
En un momento de la charla @yhara pregunto quien usa Ruby 1.8 y a mi me llego a dar un poco de vergüenza levantar la mano
Mientras que ruby 1.9 esta muy bueno, siempre tuvo una cosa que no me gusto que es la falta de compatibilidad hacia atrás (igual esto seguramente tiene justificación relacionada con las impresionantes mejores que trae), esta característica hace que la migración a 1.9 sea difícil, no tanto por las aplicaciones hechas por uno mismo, sino por las dependencias ya que no todas las gemas funcionan con ruby 1.9.
Esto no me detendrá para migrar y la respuesta al problema de las dependencias no soportadas en ruby 1.9 es forkear las dependencias, en la gran mayoria de los casos la gema que no anda con ruby 1.9 es solo por un par de lineas que usan sintaxis no soportada por ruby 1.9, lo unico que hay que hacer para que funcione es arreglar esas lineas y listo, pero eso es un tema para otro post...

Links:
Slides de la charla que dio @yhara_en: http://ht.ly/7nOL7
Notas acerca de que voy a hacer para migrar proyectos: http://tario-project.blogspot.com/2011/11/migrating-everthing-to-ruby19.html

Cuba Web Micro Framework

En una espacio que organizaron para "Ligthing Talks" una de las charlas que dieron me llamo bastante la atención, Cuba es un framework mas minimalista que sinatra, vale la pena probarlo, me preguntaria como seria factible deployar eso a heroku

Actualizacion: el usuario maxidr aporto la info necesaria via comentarios en este post para deployar un app hecha con cuba (o con cualquier framework basado en rack) a heroku sin mayor esfuerzo, pasense por http://devcenter.heroku.com/articles/rack para mas info

Ahora, por ejemplo, asi es una aplicacion con tests incluidos:
# cat hello_world.rb
require "cuba"

Cuba.use Rack::Session::Cookie

Cuba.define do
on get do
on "hello" do
res.write "Hello world!"
end

on true do
res.redirect "/hello"
end
end
end

# cat hello_world_test.rb
require "cuba/test"

scope do
test "Homepage" do
visit "/"
assert has_content?("Hello world!")
end
end

Links:

¿Quien hace el mejor asado?

Muy graciosa la charla, despues se puso algo mas serio y explico cosas bastante interesantes. @tenderlove (Aaron Patterson), ruby commiter y rails commiter, analizo porque el router (el componente de rails que decide a que controlador llamar, que acción y con que parametros de acuerdo a la url) actual es lento en muchos casos y explico como se metio en las tripas del algoritmo de regular expression para cambiar el orden del algoritmo de búsqueda de rutas que implica evaluar un mismo texto contra varias expresiones regulares.
El resultado de esa investigación fue Journey, un nuevo enrutador con un algoritmo mas optimo y por lo tanto mas rapido para mas cantidad de rutas. Este se integrara a rails seguramente para la version 3.2

Links:


Super Nario GC

Basicamente el GC de ruby corre en un solo thread mientras que ademas tiene que detener todos los threads en ejecución hasta que finaliza el proceso de garbage collection, Parallel Marking en resumidas cuentas hace posible un garbage collection multi-thread con las consecuencias positivas en la performance que eso conlleva.

Para demostrar cuales fueron los resultados de su trabajo, Nari mostro ahi mismo el Super Mario GC que mostraba en pantalla estadisticas del GC e instanciaba objetos a proposito para provocar que se invoque el GC a cada rato.

Cuando corrio el juego con su implementacion del GC las pausas ocasionadas por este casi no se veian ni se notaban, solo se podia apreciar por un texto en el medio de la pantalla que titilaba una fraccion de segundo cuando el GC se ponia a trabajar, sino no habia manera de saber que el GC estaba trabajando, despues cuando corrio exactamente lo mismo con el GC clasico las pausas pasaban a ser dolorosas para la dinamica del juego.
Nari explico que en la implementacion actual el 30% del CPU era invertido en el GC "Stop-the-world" y que la implementacion de Parallel marking ganaba un 40% de ese tiempo invertido, esto considerando que las pruebas las hizo con un procesador de dos nucleos, pero si se ejecutara en procesadores de 4 u 8 nucleos (que mas o menos es lo que tienden a salir los procesadores asi por estos tiempos) el tiempo invertido en GC seria mucho mucho menor

Ojala que esa optimizacion se incorpore pronto.

El Cuento de los Tres Arboles (en ingles TTT)

@chacon explica en detalle lo que pasa con el subcomando reset de git. Los que nunca usaron git quedaron :O porque sin contexto es muy difícil entender de que se estaba hablando, los que usan git a diario seguramente sacaron algo nuevo de la charla. Espero que mucha gente haya perdido el "miedo" al reset y aprendido que reset --hard usualmente es una pesima idea.
Para aquellos experimentados en git (como yo, muahahahahhahaha) la charla no represento ninguna novedad en lo técnico pero fue una buena lección de como dar lecciones (con diagramas, dibujitos, comparaciones, etc...)

Github wants you

Aparentemente github no descarta la busqueda de talentos mas alla de las fronteras de EEUU donde residen sus headquarters, incluso en lugares donde *actualmente* (por lo menos hasta donde yo se), github no tiene oficinas, porque un lema al que puso enfasis fue "work where and when you want".
@mojombo, Tom Preston-Werner (vendria a ser algo asi como el Batman de git con un logo de pulpo en lugar de murcielago) explico como empezaron github y con muchos estímulos visuales (talvez, creo yo, un poco exagerados) se dedico a convencernos de ir (vacaciones flexibles, seguro medico, ambiente distendido, esas cosas).
Yo, personalmente, no creo que github en ese sentido sea muy diferente a otras compañías, pero trabajar ahi seria muy interesante, por las cosas que hacen que es algo que todos lo ven desde la perspectiva de usuario de la plataforma o "superfan"

Aca la deck de @mojombo:
Igualmente nada se comparara con haber visto esa presentacion en vivo

Ruby hasta en el drinkup

Ni sabia que habia una bebida que se llamaba Ruby (el nombre completo es Absolute Ruby Red) , también vi un lambda el domingo cuando iba al RubyFunDay y la patente del taxi en el que volvi despues del drinkup decia "GEM"

RVM

No hubo una charla acerca de eso, pero hablando con otros rubystas durante la conferencia me di cuenta que tendría que probarlo. Al final lo instale y me di cuenta de que es una magnifica herramienta, sobre todo imprescindible cuando se tiene que trabajar con múltiples versiones de ruby de manera comoda (ejemplo: buscar que una gem sea compatible con ruby 1.8 y ruby 1.9)

Como nota final, talvez me este olvidando de algo, pero ya llego la hora de cortar el post... cualquier cosa seguramente habrá una segunda parte de este post si queda algo mas que decir.


sábado, 15 de octubre de 2011

¡concluyo CodeCamp 2011!

Y me puse la camiseta para dar una charla de git, junto con mi colega Nico Paez, quien obviamente no tardo en escribir este post acerca del tema (les recomiendo visitar el post ya que da acceso a interesantes recursos)

La charla que di

Gestion de la configuracion con nuget y Git (si, nuget tachado), la charla mas que nada empezo siendo iniciativa de Nico Paez quien se ve que la tiene muy clara en la oratoria sobretodo en lo didactico (enseña en la UBA) y se logro una exposicion muy copada, a pesar de que realmente no nos alcanzo el tiempo (esto mas bien significa que teniamos mucho para decir, y que sobre siempre es mejor a que falte ;) )
Cabe aclarar que Nico posee profundos conocimientos de muchos otros temas (los que hicieron posible la presentación). Aun asi, sus conocimientos de git todavia no son suficientes para que pueda ver 100% de las ventajas que git ofrece y tuve que dar un empuje (push?) en ese sentido en etapas de preparacion de la presentacion.

A los planteos de "seguir el tema", lo mas probable es que escriba algunos cuantos post, con resumenes tecnicos y continuando lo que quedo pendiente de la charla y no pudo ser en el momento

Por ultimo quiero felicitar a Nico Paez pues ha sido un gusto compartir esa actividad y tuvo mas aceptacion de lo que me imaginaba (vean los smiles en la foto). Ademas saque una enseñanza importante acerca de las presentaciones con diapositivas:
NO hay que poner diapositivas llenas de texto porque distraen al publico de lo que el/los oradores dicen, hay que recurrir a graficos, o a titulo sencillos que indiquen de que se esta hablando, en ocasiones yo como publico tambien me distraje leyendo diapositivas con texto

Links de la charla:

Las charlas a las que fui

Actualizacion: Ahora si funciona el sitio codecamp, talvez el dia de la jornada quedo saturado, ahi agregue los links


¿Que mas hay que decir? ¡Juegos multiplayer! ¡Sentencias/presagios de muerte para flash! ¡Java Lopez! De chico tenia el berretin de hacer jueguitos, despues los hice con QBasic (me siento viejo :S) , despues con VB, despues con Div Games Studio, pero estas historias son para otro post. Lo importante es que volver al mundo del desarrollo videojueguil con esta clase de tecnologias (HTML5 y demas yerbas) seria volver por una de las puertas grandes


Impresionante charla, queria saber en que estado estaba eso del XNA. Y por lo visto logran cosas muy copadas (con 3D y todo), pero para mi gusto demasiado exclusivo de plataformas microsoft, por el momento me inclinaria mas al HTML5 con javascript, o Java, algo que corra "en todos lados"


El pasado lo conociamos casi todos (esta en los libros), el presente lo vi (y no me gusto), a mi y a la mayoria de los presentes en esa charla nos intrigo el futuro,
A mi me gusto la charla, me entere de cosas que no sabia que existian (¡C++ tiene lambdas!) y tambien de cosas del nuevo c++ que hay en windows 8, que no tiene garbage collector ni es managed (a cambio tiene la mega-performance y el bajo nivel) pero tiene reference counting integrado con el lenguaje, interaccion casi "magica" con cualquier otro lenguaje como por
ej javascript y seguro un monton de cosas mas que el tiempo no da para explicarlas todas en una sola charla.
No me gusto cierta parte del mensaje tanatico, si puede llamarselo asi, que anuncia que "todo estara en c++" (igual solo es una forma de decir), fuera de ese detalle la charla me gusto bastante y el c++ con todas las implementaciones a nivel IDE que agregaron ahora sera mas "soportable"

Masas de desarrolladores, masas de chocolate

Masividad de desarrolladores talentosos exponiendo ideas y/o curiosos en la cacería de
conocimiento
Masividad de azucar, masas y cafe masivo... la comida/bebida
ideal para las 24x7 de la mayoria de los informaticos, y que en realidad no llevan a la practica por falta de dinero/infraestructura hepatica capaz de procesar toneladas de glucosa diaria

Disclaimer: no llegue a sacarle fotos a las masas, pero eran del estilo de las que se ven en la foto y eran ricas

Unicas Criticas

A la tarde se acabo la azucar (o no se conseguia) para el cafe :(, lo perdono al considerarlo tambien una buena medida para controlar el consumo adictivo de glucosa (combinado con el sedentarismo tipico de la profesion IT puede llegar a ser dañina) y teniendo en cuenta de q las masas ya proveian la sobredosis necesaria de glucosa

No podia ir a las 10 charlas que habia en cada horario a la vez, si bien no eran todas taaaaan interesantes, habia horarios en los que era muy dificil decidir entre dos o tres sesiones interesantes que habian al mismo tiempo