A small snippet for testing.
If you want to add some special actions before and after the execution of each test, and don't want to add it to setup and teardown because you will be repeating your code for each unit test and functional test, or because it is a block, you can do an alias_method_chain for the run method:
module Test module Unit class TestCase def run_with_my_block(*args, &block) Cache.clean # code before a_block_that_you_want_to_execute do run_without_my_block(*args, &block) end # Code after end alias_method_chain :run, :my_block end end endYou can redefine it at the beginning of your test_helper.rb for example.
Note that this code is only for Rails, becaus of the use of alias_method_chain function.
Google Maps is, may be, the coolest service for integrating maps in your web applications: it offers a powerful and easy API with no limit usage.
The problem is that it loads quite Javascript that has to connect to the main Google Maps page in order to draw our map. In order to avoid that we can use static Google Maps, it is, a picture (generated in real time) of the map we want to visualize. The problem with this is that you can't interact with the map (because it is an image) and that there is a limitation per day. But may be you find it useful in a particular moment.
For example, in iwannagothere.net we have a small map in every place that shows the location of that city:
In that situation we can change the map because the map is not for navigating along the city. For that you have a map in each item.
In Ruby on Rails, the programming framework of iwannagothere.net there is a gem called static-gmaps that does the hard work for you. What's more, we have found the way to integrate this maps with attachment_fu, in order you save a copy of the map in your filesystem and then avoid the day limitation usage.
Basically we have an attachment_fu kind of model (nothing special here):
class PlaceMap < ActiveRecord::Base belongs_to :place has_attachment :content_type => :image, :storage => :file_system, :processor=> :rmagick, :path_prefix => 'public/userfiles/place_maps', :max_size => 1.megabyte validates_as_attachment endThe we generate the static map instance:
map = StaticGmaps::Map.new :center => [ place.lat, place.long ], :zoom => 12, :size => [ 334, 144 ], :key => APP['gmkey']And save it in our PlaceMap model:
PlaceMap.create(:uploaded_data => (open(map.url)), :place_id => place.id, :content_type => 'image/gif')The problem here is that we are not uploading a file in the usual way: we are trying to save a raw of data. Attachment_fu doesn't know how to do that, so we have to apply a little patch:
module Technoweenie module AttachmentFu module InstanceMethods def uploaded_data=(file_data) return nil if file_data.nil? || file_data.size == 0 self.content_type = file_data.content_type self.filename = Time.now.to_i.to_s+'.gif' if file_data.is_a?(StringIO) file_data.rewind self.temp_data = file_data.read else self.temp_path = file_data end end end end endHere we are giving a random filename, generated from the current time.
And that's all, really easy :)
iwannagothere.net is the last project from mamuso, Maria and me. It's a site about traveling with two main purposes:
It's a kind of independent and high quality information travel guide.
As in unvlog.com we developed it in Ruby on Rails, (now running version 2.1), in our free time, along 3 months. Now we are refining a lot of details, and adapting some parts that we have seen people don't use as we thought.
We are going to explain all the technical issues we had in a serie of small posts in this blog or in the iwannagothere's blog. As well, we are going to present it at Spanish Rails Conference 08 in November.
We hope you enjoy the site and find it useful.
I think that the moment has arrived. This blog switches to English (to my bad English, that surely all Spanish will understand), because this is the only way to participate in the conversation of the international community.
AGU is a three letters word that stands either for my short-name and for the ARNm triplet that codes Serine, an amino acid presented in all of us.
As you may remember from school, biology is built from tiny parts that just interact between themselves in a mechanical way that leads to bigger, greater and complex things.
The little strands called DNA, replicated almost one hundred trillion times in your body, and which could surround the entire earth (each strand), have written in them each detail of what you see every morning in the mirror.
At some point in the cell's life, those strands start to get transcribed into RNA chains, a middle-man molecule in the process of polypeptides synthesis.
Once a polypeptide strand is completed by hundreds and even thousand amino acids, it starts to fold in unpredictable forms until it shapes the final structure, revealing a protein, the engine of life.
This plethora of magical steps occurs in a deterministic way, several times per minute in every single organism.
Do you recognize this?:
gagtgcttgg gttgtggtga aacattggaa gagagaatgt gaagcagcca ttcttttcct gctccacagg aagccgagct gtctcagaca ctggcatggt gttgggggag ggggttcctt ctctgcaggc ccaggtgacc cagggttgga agtgtctcat gctggatccc cacttttcct cttgcagcag ccagactgcc ...
This is an extract from the DNA which codes the p53 protein, one of the most globally studied molecules involved in cancer development, well known as the star of cancer suppression proteins.
And what about this other piece of code?:
8B542408 83FA0077 06B80000 0000C383 FA027706 B8010000 00C353BB 01000000 B9010000 008D0419 83FA0376 078BD98B C84AEBF1 5BC3
This strange code is all you need to program the fibonacci serial in the low-level machine language. Executable by almost every gadget around you. See what both codes have in common?
Scientists and tech people have worked really hard during last decades building levels of abstraction. Look inside and you will find a large amount of conceptual layers from ones and zeros to the graphical user interface, each one simpler than the previous. All drives in the direction that nobody needs to think on hexadecimal to send a plain email.
Have you ever think about a cell as a machine?. They really behave like it whether they are yeast or pluripotent cells in your bone marrow. In fact, as Drew Endy define them, they act as computational systems. They receive inputs, and behave accordingly as outputs. Cells have measurements tools, priorities to satisfy and self awareness of different kinds.
DNA is a reference of functions for a certain being, as software is for an application.
The only difference between software and life source code is the abstraction layers created that enables us to understand, write and debug what we do in a computer. Fortunately, that complex frontier between life in nature and what can be done in a lab by humans is breaking down throughout international cooperation in biology and health research.
Knowledge repositories about enzyme interactions in pathways, expression rules of genes and protein transcriptions are spreading all over the web in different public databases.
Although work with bulk data in these databases is still a hard task, little pieces of proteins interactions are been described and identified as functions in projects like the "Registry of Standard Biology Parts", initiated by previously cited Drew Endy. Basic biological functions are explained in its website as simple parts that get combined making devices and systems. The result is a hierarchical scheme of complex behaviors.
Craig Venter used to say "Electronic industry is based upon 12 fundamental components. Up to now, 20 million genes had been identified."
The faculty for using these genes as pieces of code in engineered organisms have an unprecedented potential in creating new things.
OK, but what does all this have in common with interaction design?. As defined in wikipedia, "Interaction Design is the discipline of defining the behavior of products and systems that a user can interact with."
As you can find in some related lectures, biology must be understood as a technology. A technology for creating complex things with complex implications.
As designers, we are used to deal with problem solving tasks, requirements, and constraints. Biotechnology industry is developing extremely fast, enabling a myriad of applications for new products and services based on biology.
Many authors describe the necessity of compartmentalize competences in biotechnology. Specialization brings better quality in every decision step. From laboratory operators to the function of a biological engineer as a technical architect, someone has to deal with the human side of the final product.
As interaction designers we can apply all the inherited knowledge in our discipline to new horizons like biotech. It's just a new framework with new variables.
Si lo llega a hacer premeditadamente seguro que no le sale. El pasado jueves día 7, coincidiendo con el día en el que cumplía mis treinta y cinco agostos, Aslak mandaba el siguiente correo a la lista de desarrollo de RSpec:
[ANN] Cucumber
Nice vegetable, nice tool.
It's my reimplementation of the story runner, addressing several
shortcomings of the current one. And I'm calling them features instead
of stories now, because that is what they are.
http://github.com/aslakhellesoy/cucumber/ (The home page)
http://gojko.net/2008/08/06/cucumber-next-generation-ruby-bdd-tool/
(Thanks Gojko)
Take a look - it's taking shape.
Aslak
Una de la principales virtudes del Cucumber de Aslak frente al Story Runner de RSpec es la posibilidad de escribir las "plain text stories" en cualquier idioma.
Lo cachondo del asunto es que Aslak tiene asignada la implementación de dicha funcionalidad dentro de RSpec desde que la solicité a primeros de año junto con el parche para la versión de aquel momento y, como no, su "plain text story" asociada:
Story: Writting stories in other languages As a non-english RSpec developer I want to write stories in my mother tongue So that I don't have to make an extra effort to know what's going on Scenario: Pending Given the file stories/plain_text_story_in_spanish.rb When I run it with the ruby interpreter Then the exit code should be 0 And the stdout should match /1 scenarios: 0 succeeded, 0 failed, 1 pending/m And the stdout should match /4\) La portada de Mi Sitio en La Red/ Scenario: Succeed Given the file stories/plain_text_story_in_spanish_with_steps.rb When I run it with the ruby interpreter Then the exit code should be 0 And the stdout should match /1 scenarios: 1 succeeded, 0 failed, 0 pending/mEra muy excitante ver como la versión sin el parche fallaba al ejecutarla y la parchea campaba triunfal. Adiós TODO ambiguo. Hola Spec-ificación formal.
Sin embargo la realidad es que ha llovido bastante desde aquello, y viendo que seguramente Aslak escribirá sus historias en noruego utilizando Cucumber, me da la sensación de que seguirá lloviendo durante mucho más hasta que dicha posibilidad exista en la versión oficial de RSpec.
Espero probar Cucumber pronto, pero mientras tanto no me queda más remedio que mantener el legado que tenemos actualmente utilizando el Story Runner de RSpec. Para ello me he creado una rama de RSpec y le he metido los cambios para el soporte multilenguaje.
En cualquier caso lo que está claro es que Aslak ha resuelto mi deseo y me lo ha presentado justo el día de mi cumple... Takk så mye!
Como ya ha comentado Enric Cid, durante el próximo mes de septiembre publicaré conjuntamente con Víctor un libro alrededor del Crossumer, concepto sobre el que venimos trabajando desde hace unos meses y que, de cara a la exposición del libro, definimos como un consumidor que
- Carece de confianza en la comunicación de las marcas (dimensión emocional)
- Conoce el backstage del marketing (dimensión cognitiva o del conocimiento)
- Presenta un papel activo en la validación de los mensajes y que participa de forma activa en el storytelling de las marcas (dimensión comportamental)
- viéndose las tres dimensiones potenciadas por el desarrollo de las nuevas tecnologías y la socialización en un contexto de elevada presión comunicativa por parte de las organizaciones.
Todo esto, leído así del tirón, abarca mucho y quizás dice poco. No pudiendo resumir el libro, vamos a centrarnos en dos cuestiones. En el próximo post, hablaremos de la naturaleza del conocimiento alrededor del consumo, y en este, repasaremos brevemente el factor "socialización en el consumo", que justifica es la base desde la que emerge esta tipología de consumidor.
España lleva al menos treinta años inserta en una sociedad de consumo madura: aquellos que nacieron tras la muerte de Franco, por poner una referencia, han sido socializados en un entorno dónde la publicidad es parte constitutiva del paisaje, con un desarrollo masivo del sector servicios y del márketing, con los resultados de la investigación de mercados haciéndose pasar por noticia en los medios y con una acelerada comercialización del espacio público y de las subjetividades. En este tiempo, ha presenciado estrategias de posicionamiento de las marcas tan dispares como la publicidad comparativa de Don Simón, las campañas de responsabilidad social corporativa de Iberdrola, el "busque y compare", los detergentes que muestran a amas de casa sorprendidas por la ropa sin mancha, el "yo no soy tonto" de Media Mark y la Verdad Verdadera de Yoigo,..., cada sesión de anuncios en televisión es una pequeña lección de marketing. La saturación publicitaria, las experiencias insatisfactorias como cliente/consumidor y la conciencia de la intencionalidad de las comunicaciones corporativas han acabado por producir los rasgos desde los que nace el crossumer:
- En lo emocional, ha desarrollado una actitud de desconfianza, de desligamiento, respecto a los mensajes de las organizaciones. De lo que te cuentan, la mitad, o menos.
- En lo cognitivo, la socialización en un entorno de presión comunicativa ha generado un aprendizaje sobre las estrategias de los profesionales de marketing, de manera que se decodifican las intencionalidades detrás de las acciones publicitarias. Conforme a los resultados de un estudio que realizamos en 2007, el 42% de los internautas ha estudiado alguna asignatura relacionada con el marketing, y entre un 80% y un 100% dice conocer los significados de términos sectoriales como "eslogan", "campaña", "spot" e"imagen de marca". Conviene no perder de perspectiva que la asignatura de Educación para la Ciudadanía contempla como contenidos curriculares en la ESO "El consumo racional y responsable. El reconocimiento de los derechos y deberes del consumidor. La influencia del mensaje publicitario en los modelos y hábitos sociales". Esto es, la próxima cohorte generacional habrá recibido, de manera formalizada, una primera aproximación al mundo del marketing.
Estos aspectos cognitivos y actitudinales hacia el marketing tienen un impacto comportamental gracias a las nuevas tecnologías: si antes de la web, la socialización en un entorno publiciatario asfixiante ya era un hecho y es posible que el plano cognitivo tuviese ya un elevado desarrollo, Internet ha operado de palanca gracias a la que es posible que el usuario adopte un rol activo, contraste los mensajes de los anunciantes (recurriendo a opiniones de otros consumidores, visitantes intermediarios, ...) e intervenga en el storytelling de las marcas, en las narraciones que las organizaciones realizan sobre quiénes son y para qué operan. En este sentido, es ejemplar el caso de Mercadona: durante una huelga mantenida en 2006, los sindicalistas de la CNT, conscientes de la necesidad de impactar en la opinión pública, y también conscientes de su incapacidad para hacerlo a través de los medios masivos, "colonizaron" diferentes espacios sociales de la web. Aún hoy, dos años después de finalizado el conflicto, si queremos informarnos en Youtube, Flickr, o el propio Google sobre Mercadona los primeros resultados que obtendremos serán contenidos generados por el sindicato, que habrá impactado sobre la comunicación que la marca desea realizar de sí misma y, lo que es también enormemente importante, lo habrá hecho de forma continuada en el tiempo: la "mancha" para la marca no se limpiará con el olvido y mayor inversión publicitaria, sino que se mantendrá a lo largo del tiempo.
Si el crossumer nace debido a un contexto de presión comunicativa (que lleva al desarrollo de la actitud de desconfianza y al incremento del conocimiento de las interioridades del marketing), y toma carácter activo por el desarrollo de las tecnologías (cuya penetración se extenderá pregresivamente), es posible pensar que el crossumer acabará por ser, no tanto un tipo de consumidor emergente, sino la descripción del consumidor futuro.
Sin ser demasiado mayor, ya lleva uno varias experiencias de derrota, y son las colectivas y que tienen que ver con lo que se ha sido de niño y adolescente las que más duelen. Me cabrea quedarnos sin el estadio dónde pasé tanto tiempo, a manos de unos delincuentes convictos , me desespera cómo IU va de descalabro en descalabro de mano de gente que no se sabe si son irresponsables, incapaces o directamente están interesados en hacerla desaparecer,..., pero medianamente se acaba asumiendo. Ahora, quedarse sin Fiesta del PCE es un palo muuuuuy gordo. Son 13 asistencias en los últimos 14 años. Marcos Ana, La Brigada Víctor Jara, los conciertos de flamenco, Rosendo, Bertinotti, los zapatistas y el Sáhara, los mojitos y la sidra, Anguita, los choricitos, el rincón cubano y el de Córdoba, y otra vez Rosendo, el viejito chiquitín que llevaba una banderón de cuatro veces su altura, las empanadas y el sobao pasiego, la Internacional, ...
Motivos hay muchos: uno me cabrea particularmente aunque será de los menos relevantes, esas avalanchas de costras enfrentándose al capitalismo mediante el salto de vallas para ahorrarse 20 euros kalimocheros. En todo caso, el declive el año pasado era palpable para quien quisiera verlo. Envidia me dan nuestros vecinos portugueses: la vitalidad de su Fiesta no es casual, tiene que ver con la pretensión de tener un partido vivo y visible.
Mirar este sitio a través de Wordle…
Pensar en desuscribirme…
Technorati Tags:Llevaba tiempo con ganas de probar JRuby y Glassfish. También de jugar con Merb y de darle un poquito de alegría a la FreeBSD que tengo para trastear.
Hace algún tiempo me encontré con este post de Nodeta que parecía servirme para matar tres de los mencionados pájaros de un tiro.
Sólo me faltaba la información necesaria para mi cuarto y último deseo: hacerlo en FreeBSD. El post de Nodeta lo resolvía en Ubuntu, pero en principio lograrlo en FreeBSD no tenía porque ser demasiado complicado.
Pues la primera en la frente: los binarios de Glassfish estaban disponibles para un buen puñado de plataformas (Solaris, AIX, Window, MacOS y GNU/Linux) pero no para FreeBSD. Eso sí, para los más valientes Sun ofrece el repositorio de CVS con los fuentes.
Se me hacía la cosa un poco cuesta arriba pero no tardé en descubrir un post de Homer Yau, un empleado de Sun, que comentaba como se podía hacer la cosa.
Para instalar Merb, además de las gemas mencionadas en el post de Nodeta tuve que instalar las siguientes:
Respecto a la instalación de GlassFish comentar que perdí bastante tiempo por no tener en cuenta la nota 4 del post de Homer. En la misma se menciona la posibilidad de establecer la versión concreta de los fuentes de GlassFish que nos vamos a bajar de Sun (la etiquetada como SJSAS90_FCS_BRANCH). Al bajarse una versión más modernas aparecian dependencias no resueltas no mencionadas en el post al hacer el paso 4 (maven build, en particular con el HK2 que parece ser la nueva base del nuevo GlassFish para hacerlo ligero ligero).
Ah! Por cierto, unas cuantas versiones, que nunca está de más:
Seguimos con truquitos de shell para desarrolladores, en este caso de Ruby. Os estoy enseñando mi ~/.bash_profile por fascículos
En este caso se trata de estar en concidiones de acudir al viejo aforismo "si todo lo demás falla, consulta el manual", en nuestro caso con las gemas de ruby que tengamos instaladas y que, mejor o peor, suelen venir documentadas.
No sé si conocéis el comando gem server (deberíais). Levanta un servidor web (creo que es un Webrick) en el puerto 8808 de nuestra máquina, apuntando directamente a la documentación de las gemas. Nos bastará apuntar nuestro navegador favorito a http://localhost:8808/, buscar la gema en cuestión, y ponernos a leer.
Pero se puede hacer más cómodo aún, metiendo esto en nuestro ~/.bash_profile:
export GEMDIR=`gem env gemdir` gemdoc() { open $GEMDIR/doc/`$(which ls) $GEMDIR/doc | grep $1 | sort | tail -1`/rdoc/index.html } _gemdocomplete() { COMPREPLY=($(compgen -W '$(`which ls` $GEMDIR/doc)' -- ${COMP_WORDS[COMP_CWORD]})) return 0 } complete -o default -o nospace -F _gemdocomplete gemdocLa segunda función y la última línea son para dar autocompletado al comando, lo cual lo hace aún más atractivo para vagos. Por cierto, yo nunca le había metido mano al autocompletado en bash y tiene pinta de ser bastante simple la cosa, si investigo algo más ya os contaré.
El caso es que con la función gemdoc tendremos acceso directamente a la documentación de una gema concreta (en vez de al índice), sin necesidad de levantar el servidor (accede directamente al sistema de archivos), y además con autocompletado:
(Sacado de aquí).
Nota: según el sistema operativo, quizás necesites cambiar alguna cosa del script (en particular, puede que tengas que cambiar la llamada a open por una llamada a tu navegador favorito). Esto funciona tal cual en MacOSX.
Uno de los errores más comunes cuando llevas poco tiempo usando git (o llevas un poco más pero eres un tolai como yo) es confundirte de rama: estar en una de desarrollo pensando que estás en la master, o viceversa, y liarla parda con cualquier comando. Este truquito te permite saber en todo momento cuál es la rama seleccionada.
Añade esto en tu ~/.bash_profile:
git_branch() { git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/(\1) /' } export PS1="\u@\h:\w \$(git_branch)$ "Bueno, en la parte de \u@\h:\w pon lo que quieras o lo que tuvieras antes, eso es lo que me gusta tener a mí (usuario@máquina:directorio). Con este truquito, si estás en un directorio que es una copia de trabajo de git, el prompt te mostrará entre paréntesis la rama en la que estás:
¿A que mola? (por cierto, lo he cogido, con una mínima modificación, de aquí)