viernes, junio 01, 2007

Visualizando redes sociales: amigos en Barrapunto y menéame

He hecho dos programitas que sacan las relaciones de amistad en en el interior de dos comunidades virtuales, barrapunto y menéame. Después he sacado imágenes gráficas de dichas relaciones, para visualizar, en lo posible, la compleja estructura de esas "relaciones sociales". Aunque el análisis de los datos no es muy riguroso, el resultado puede interesar tanto a los que les gusta el análisis de redes sociales online como a los que les gusta la ver programitas de ejemplo. En este caso están hechos en Erlang, y están acompañados de algún enlace que he ido recopilando en el camino.


La red social de barrapunto

Me gusta mucho ver gráficos relacionados con las ciencias que tratan de estudiar la complejidad, como los de visual complexity*, no porque sepa mucho de ello, sino como mero aficionado. El caso es que llamó mucho la atención también la representación visual de la red social de feevy (comentado por gente que sabe de esto, de entre los cuales me excluyo, en Un mar de flores).

(*Otra actualización:Parece que alguien envió esta entrada a visualcomplexity y ha sido aceptada: Social Network of barrapunto. Gracias al anónimo submitter que lo envió. Me siento muy halagado ;) )

Pues bien, el otro día se me ocurrió que se podría hacer lo mismo con los usuarios de barrapunto, que en el fondo no deja de ser una red con unas relaciones muy bien definidas: la relación de amistad y enemistad. Y también se me ocurrió que lo podría hacer con un programita que capturara esas relaciones y las dejara en formato DOT. Para ello he usado Erlang. ¿Por qué? Pues porque si. Se podía haber hecho con wget o curl y awk, y/o perl o ... Pero bueno, me apetecía hacer algo más que un Hola mundo! en este lenguaje. Y, a decir verdad, me lo he pasado muy bien programando en él y descubriéndolo.

Comentaba Alex que para visualizar la redes sociales solían usar SocNetV, pero que en este caso usó Graphviz Ambos admiten para modelar las redes el lenguaje de definición DOT. Son los programas que yo he usado para los gráficos que viene a continuación.

Primero la imagen tal cual, sin ordenar demasiado, con socnetv:



Intentando desenredar la red, estos programas tienen criterios para representar la información en función de una serie de parámetros que suelen calcularse en función del las distintas definiciones de centralidad...


Pegaré aquí las imágenes que creo que van a dar una información más interesante. Esta siguiente está generada con el socnetv, aplicando una de las ordenaciones en circulo por centralidad (en este caso, creo, "in degree centrality"):



Usando el comando nop bp.file | twopi -Tpng -o bptwopi.png, de graphviz:



La imagen que más me gusta es esta, que da alguna información de la organización, pero acercándose uno puede ver detalles (usando nop bp.file | fdp -Tpng -o bpfdp.png)... Lo malo es que subiéndola a flickr se baja tanto la resolución como la calidad. Se admiten sugerencias para subir las imágenes a un sitio donde las dejen poner a mucha resolución...Actualización: Gracias a resete-e y su cuenta de flickr pro hay imágenes de alta resolución. Muchas gracias ;)



La red social de menéame


Mientras iba haciendo el primer programa, se me ocurrió que casi por el mismo precio podría tener un segundo programa que obtuviese los datos de menéame. Solo apuntar que en este caso la red está aún más enmarañada porque hay más actores y más relaciones...

Las imágenes análogas a las anteriores serían:
(Nota: La última imagen parece en negro, pero si se pincha sobre ella sale a resolución completa...)




Los datos

Segunda actualización: No tenía donde poner los ficheros de datos, pero Eduardo de http://hombrelobo.com/ me cedió amablemente espacio, así que todos los interesados en los datos en bruto pueden jugar con ellos y con graphviz, SocNetV y con lo que quieran. Traté de embeber los svg en HTML, pero creo que no merece la pena porque son muy grandes y firefox (al menos) se queda un poco tonto. Mejor bajárselos y verlos con algún visor... Bueno, los enlaces:
Que los disfruten ;)
"Análisis"

Se ve que hay islitas, cosa que me ha sorprendido, por aquello de los seis grados de separación, pero también lo comentaba Ugarte en su entrada. Pensándolo un poco más detenidamente, tanto en este caso como en el de los enlaces feevy son casi todas relaciones fuertes en el sentido en el que se comenta en un mar de flores. No todas las relaciones débiles entre usuarios (yo leo poco a tal, yo conozco a cual, pero no le sigo) no salen en este esquema, es seguro que en ese caso todos estarían conectados... No obstante, en el caso de las gráficas de las dos comunidades, las islas son menores que en feevy, la red está más clusterizada... (este razonamiento hay que tomarlo con precaución: yo soy sólo un aficionado ;))


Más redes


Se me pasó por la cabeza un proyecto más ambicioso en en que se definiesen parámetros de búsqueda (expresiones regulares y alguna otra cosa...) pero me resultó demasiado grande para el poco uso que le iba a dar. Si alguien tiene ganas, se puede modificar muy fácilmente para sacar la red de slashdot (casi trivial) o de digg... ¿twitter? (por cierto, que alguien sacó el gráfico de los usuarios holandeses de twitter, también vía de Ugarte)



Erlang

En otro orden de cosas... lo he programado en Erlang y ha sido una gratísima experiencia. Hay quien dice que la iteración es humana, la recursión es divina, pero Erlang con su tail recursion (recusión terminal) te la facilita o más bien te la hace obligatoria para recorrer los conjuntos de datos. Pero tanto el uso de esa recursión, el manejo de listas y tuplas como la sintaxis me ha resultado muy muy natural. El hecho de que cada "sentencia" sea separada por comas, el final un punto, las flechas... todo muy intuitivo, un poco como escribir un texto, salvando las distancias ;)


Otro punto fuerte de el lenguaje es el tratamiento de la concurrencia, que es muy sencillo teniendo en cuenta una serie de premisas que ya comentó Joe Armstrong en su entrevista en Thinking parallel. Erlang no usa threads nativos sino que tiene sus propios "procesos ligeros" con lo que logra una gran escalabilidad en cuanto a número de procesos disponibles.


En este ejemplo no se observa muy bien, porque no creo que el programa lo requiriese, pero el lector atento del código podría añadirle una cierta concurrencia para hacer peticiones en paralelo, pero en este caso no es muy útil...


Aquí voy a pegar el código que he usado tal cual, con la advertencia que no es un código muy probado y tal y cual, etc, etc :)
(por cierto y a modo de recordatorio, el comando que he usado para generar el código HTML con resaltado de sintaxis es enscript --highlight=erlang --color --language=html --output=soc_graph.html soc_graph.erl)
Blogger se comió los tabuladores, los he sustituido por espacios...
El programa de barrapunto:



-module(soc_graph).
-export([do_it/0]).
-export([get_friends/1]).
-export([get_users/1]).

do_it() ->
init_file(),
get_users({self(),1}),
end_file().

%get_users gets user list
get_users({Pid,Step}) -> get_users(0,{Pid,Step}).
get_users(Pan,{Pid,Step}) ->
URL=io_lib:format("http://barrapunto.com/search.pl?threshold=-1&op=users&sort=1i&start=~.10B",[Pan]),
{ ok, {Status, Headers, Body }} = http:request(URL),
{match, Matches}=regexp:matches(Body,"barrapunto.com/~.*/journal"),
Lst_new = [string:substr(Body,Start+16 ,Length-16-8 ) || {Start,Length} <- Matches],
case Lst_new of
[] -> get_users_done;
%_ -> spawn(soc_graph,get_friends,[{Pid,Lst_new}]),
_ -> get_friends({Pid,Lst_new}),
get_users(Step+Pan,{Pid,Step})
end.

%get_friends gets user id and get friend list
%Pid is unused (refactoring?)
get_friends({Pid,[H|T]}) ->
URL=io_lib:format("http://barrapunto.com/~~~s/friends",[H]),
io:format("~s~n",[H]),
{ ok, {Status, Headers, Body }} = http:request(URL),
Reg_exp="barrapunto.com/~.*/friends",
{match, Matches}=regexp:matches(Body,"barrapunto.com/~.*/friends"),
Frnd_new = [string:substr(Body,Start+16 ,Length-16-8 ) || {Start,Length} <- Matches],
New_user=replace_forb_chars(H),
Frnd_flt=lists:filter(noself(New_user),Frnd_new),
to_file([{H,Frnd_flt}]),
get_friends({Pid,T});
get_friends({Pid,[]}) -> ok_friends.

noself(H) ->
fun(S) ->
case regexp:match(S,H) of
{match,_,_} -> false;
nomatch -> true;
{error,_} -> true
end
end.

%replace_forb_char replaces special (regexp) characters in user name
replace_forb_chars(S) ->
replace_forb_chars(S,".$()*+").
replace_forb_chars(S,[RH|RT]) ->
Regexp="["++[RH]++"]",
{ok,Newstr,_}=regexp:gsub(S,Regexp,Regexp),
replace_forb_chars(Newstr,RT);
replace_forb_chars(S,[]) ->
S.



%to_file writes friends into DOT file
to_file(Frnd) ->
%this line violates DRY (Refactor?)
{ok,F}=file:open("bp.file",[write]),
to_file(F,Frnd).
to_file(F,[{User,Frnds}|T]) ->
%TODO: Format of map/frineds
Out_Frnd= fun(Frnd)-> io:format(F,"\"~s\" -> \"~s\"~n",[User,Frnd]) end,
lists:map(Out_Frnd,Frnds),
to_file(F,T);
to_file(F,[]) ->
file:close(F),
ok_to_file.

%init_file initializes the DOT file
init_file() ->
%this line violates DRY (Refactor?)
{ok,F}=file:open("mnm.file",[write]),
io:format(F,"digraph mydot {~nnode [color=red, shape=ellipse];~n",[]),
file:close(F).

%end_file inserts the coda in the DOT file
end_file() ->
%this line violates DRY (Refactor?)
{ok,F}=file:open("mnm.file",[append]),
io:format(F,"[weight=1, color=black];~n}~n",[]),
file:close(F).


La modificación para menéame:




-module(soc_graph).
-export([do_it/0]).
-export([get_friends/1]).
-export([get_users/1]).

do_it() ->
init_file(),
get_users({self(),1}),
end_file().

%get_users gets user list
get_users({Pid,Step}) -> get_users(1,{Pid,Step}).
get_users(Pan,{Pid,Step}) ->
URL=io_lib:format("http://meneame.net/topusers.php?sortby=0&page=~.10B",[Pan]),
{ ok, {Status, Headers, Body }} = http:request(URL),
{match, Matches}=regexp:matches(Body,"/user/[^\"]*"),
Lst_new = [string:substr(Body,Start+6 ,Length-6) || {Start,Length} <- Matches],
case Lst_new of
[] -> get_users_done;
%_ -> spawn(soc_graph,get_friends,[{Pid,Lst_new}]),
_ -> get_friends({Pid,Lst_new}),
timer:sleep(1000),
get_users(Step+Pan,{Pid,Step})
end.


%get_friends gets user id and get friend list
%Pid is unused (refactoring?)
get_friends({Pid,[H|T]}) ->
URL=io_lib:format("http://meneame.net/user/~s/friends",[H]),
io:format("~s~n",[H]),
Reg_exp="friends_of=[^\"]*",
{ ok, {Status, Headers, Body }} = http:request(URL),
{match, Start, Length}=regexp:match(Body,Reg_exp),
User_Id = string:substr(Body,Start+11 ,Length-11 ),
Frnd_new=get_friends_page(1,User_Id,[]),
New_user=replace_forb_chars(H),
Frnd_flt=lists:filter(noself(New_user),Frnd_new),
to_file([{H,Frnd_flt}]),
get_friends({Pid,T});
get_friends({Pid,[]}) -> ok_friends.


%get_friends_page gets friend list
%Pid is unused (refactoring?)
get_friends_page(Page,User_Id,Frnd) ->
Reg_exp2="/user/[^\"]*",
URL2=io_lib:format("http://meneame.net/backend/get_friends_bars.php?id=~s&p=~.10B&type=from",[User_Id,Page]),
{ ok, {Status2, Headers2, Body2 }} = http:request(URL2),
{match, Matches}=regexp:matches(Body2,Reg_exp2),
Frnd_new = [string:substr(Body2,Start2+6 ,Length2-6) || {Start2,Length2} <- Matches],
case Frnd_new of
[] -> Frnd;
_ -> get_friends_page(Page + 1,User_Id,lists:append(Frnd,Frnd_new))
end.

noself(H) ->
fun(S) ->
case regexp:match(S,H) of
{match,_,_} -> false;
nomatch -> true;
{error,_} -> true
end
end.


%replace_forb_char replaces special (regexp) characters in user name
replace_forb_chars(S) ->
replace_forb_chars(S,".$()*+").
replace_forb_chars(S,[RH|RT]) ->
Regexp="["++[RH]++"]",
{ok,Newstr,_}=regexp:gsub(S,Regexp,Regexp),
replace_forb_chars(Newstr,RT);
replace_forb_chars(S,[]) ->
S.

%to_file writes friends into DOT file
to_file(Frnd) ->
%this line violates DRY (Refactor?)
{ok,F}=file:open("mnm.file",[append]),
to_file(F,Frnd).
to_file(F,[{User,Frnds}|T]) ->
%TODO: Format of map/frineds
Out_Frnd= fun(Frnd)-> io:format(F,"\"~s\" -> \"~s\"~n",[User,Frnd]) end,
lists:map(Out_Frnd,Frnds),
to_file(F,T);
to_file(F,[]) ->
file:close(F),
ok_to_file.

%init_file initializes the DOT file
init_file() ->
%this line violates DRY (Refactor?)
{ok,F}=file:open("mnm.file",[write]),
io:format(F,"digraph mydot {~nnode [color=red, shape=ellipse];~n",[]),
file:close(F).

%end_file inserts the coda in the DOT file
end_file() ->
%this line violates DRY (Refactor?)
{ok,F}=file:open("mnm.file",[append]),
io:format(F,"[weight=1, color=black];~n}~n",[]),
file:close(F).


Referencias sobre Erlang

jueves, mayo 03, 2007

¿Postel o Dracón?

La primera vez que leí sobre la ley de Postel: "Sé conservador con lo que envias, liberal con lo que recibes"(*) me pareció tan filosóficamente interesante que intenté escribir una entrada al respecto, pero no supe, porque no tengo el gen gurú necesario para ello. Por eso, no está mal recurrir a los gurús de verdad, que sean ellos los que digan parte de lo que le ronda a uno por la cabeza. El caso es que en una semana dos blogstars de esto de la programación y la tecnología han comentado algo relacionado, así que les cedo la palabra, claro (cada una de las entradas da mucho más de si, pero claro, para eso está enlazadas, para que se lean ;)):

(*)Otras veces nombrado como "Sé conservador con lo que haces, liberal con lo que aceptas de otros". El enunciado es susceptible de ser políticamente interpretable más aún en esta segunda encarnación del principio. En este caso yo creo que es más bien interpretable desde el punto de vista de la ética. Como referencia se puede leer lo que dice Tim Berners-Lee acerca de esto y de una frase (que fué durante un tiempo firma mía) acerca del funcionamiento descentralizado "We have no kings or presidents. We believe in rough consensus and running code". Eso si, con grandes influencias de Unitarismo universalista, una religión más o menos buenrollista, si es que eso es posible...


"¿Postel o Dracón?" en barrapunto

lunes, abril 30, 2007

Entrevista sobre YARV

Vía la sección de reddit de programación (que a pesar de su sistema de filtrado y puntuación, también tiene el mal del exceso de información... ) he encontrado una serie de entrevistas sobre la nueva máquina virtual que ejecutará Ruby: YARV. Responden las dos personas más involucradas en ello, Matz (recordemos, el creador del lenguaje) y a Koichi Sasada, el desarrollador principal.

En la segunda parte de la entrevista se habla de las distintas implementaciones de los entornos de ejecución de Ruby. Por resumir, Koichi dice: "Necesitamos especificaciones, buenos test y buenos benchmarks". Por las bitácoras de barrapunto se ha hablado de ello, porque Robert h Quinn está trabajando en los test, según comentaba en GSoC 2007 : De que va mi proyecto

Sobre todo me ha gustado la tercera parte, sobre el pasado el presente y el futuro de los threads en Ruby.En esta parte se argumentan las razones por las que se abandonó la implementación de threads en espacio de usuario por el uso de los threads nativos del sistema, además de explicar como eso afecta el soporte de continuaciones.
(Hablamos de estas cosas hace unos meses en Noticias sobre Ruby 2.0 (que al parecer no son sobre 2.0 estrictamente...)

Actualización: Como me comenta Robert h Quinn, en On Ruby tienen una serie de entrevistas a los desarrolladores de distintas implementaciones de entornos de ejecución de Ruby. Más para leer...


"Entrevista sobre YARV" en barrapunto

miércoles, abril 18, 2007

Programando con Erlang

Dave Thomas ha escrito una serie de apuntes introductorios a erlang, aprovechando el nuevo libro, Programming Erlang de Joe Armstrong (un esfuerzo publicitario, porque el libro se publica bajo el amparo de los programadores pragmáticos, pero aquí nos da igual, ¿no?)

Entonces pasemos a los enlaces:

Y algunos enlaces más

Publicitado también desde los programadores pragmáticos... ¿le pasará lo mismo que a Ruby? ¿tendrá el mismo crecimiento? Personalmente lo dudo, a pesar de que el lenguaje tiene unas características muy interesantes, entre otras el tratamiento de la concurrencia. La principal pega la comenta el propio Armstrong en el artículo introductorio: ¿Es Erlang difícil? No, pero es diferente.

(Se habló en barrapunto de él hace bastante tiempo en Otro lenguaje de programación: Erlang)


Programando con Erlang en barrapunto

martes, abril 17, 2007

Twitter, RoR, escalabilidad y flames

Ha sido imposible escapar al contrahype: un desarrollador de twitter, el servicio webdospuntocero de moda (¿o ya no está de moda?, no sé, a mi que no me pregunten, que yo en estas cosas estoy muy démodé), Alex Payne, declaró que Ruby on Rails no escala, que tiene un cuello de botella en la base de datos (comentado en barrapunto en Entrevista con Alex Payne, uno de los desarrolladores de Twitter) y se desató el multiflame. Debido a la relevancia y al ruido conseguido por los fans de RoR parece que se les tenía ganas... El hecho es que se ha levantado una polvareda de bytes bastante importante, lo que en estos tiempos significa una conversación fragmentada de post cruzados en muchísimos blogs y alguna lista de correo, que aún quedan :)

Tengo que reconocer que me gustan los flames, sobretodo si no me tocan de cerca, porque en general y con un poco de suerte, de tanto ruido se puede extraer información interesante...

Aunque, debo confesar, esta vez me ha sorprendido que la onda expansiva ha llegado hasta la blogosfera hispana, cosa que no suele ser usual... Primero pues, los enlaces en castellano. Ah, seguro que me dejo algo, se admiten sugerencias de enlaces interesantes :)

Ahora en inglés. De David Heinemeier Hansson:Ha habido respuesta de diversa índole, pero se pueden rastrear fácilmente. Solo voy a resaltar alguna que se va por las ramas, que son las que más me interesan ;)

Dice Juan Lupión en "sobre railes" que permanezcamos a la escucha. Desde luego, un flame es un flame ;)

Twitter, RoR, escalabilidad y flames en barrapunto

martes, abril 10, 2007

Orientación a objetos: algunas críticas

Vía Reddit me he encontrado con un escrito, intencionadamente provocador diría yo, de Joe Armstrong (de nuevo): Why OO Sucks. No obstante me gustaría resaltar los argumentos, que dan que pensar y para eso estamos aquí:
  • Las estructuras de datos y las funciones no deberían ir juntas:
    Esto es una característica en principio ventajosa de la POO, pero puede ser una servidumbre, además de que no deja aprovechar algoritmos genéricos al estilo de C++ con la STL. No obstante hay que decir que variaciones de la programación orientada a objetos permiten el Duck typing, como en python o ruby que favorece la posibilidad de hacer algoritmos más genéricos...
  • Todo debe ser un objeto:
    Relacionada con la anterior, todo dato debe ser un objeto y tener la parafernalia necesaria para serlo. En esto los lenguajes van mejorando, creo yo, reduciendo lo necesario para ser objeto, a veces haciéndolo implícito.
  • La estructura de datos está dispersa por todos lados:
    Y no le falta razón. Esto es particularmente importante si las estructuras de datos van a ser usadas para hacer la interoperabilidad entre sistemas heterogéneos
  • Los objetos tienen un estado privado:
    Esta es una crítica muy desde la perspectiva de la Programación funcional (bueno, las otras también...) pero muy interesante. La primera vez que oí eso de que en Erlang (por ejemplo) no se podía reasignar variables me resultó muy chocante, pero ver hacer las cosas de un modo diferente es muy ilustrativo a veces... Es el "truco" de estos lenguajes de no usar el estado para evitar efectos laterales, muy relevante también para programación concurrente.

Mi opinión sobre el tema ya la expresé en ¿Ha muerto la orientación a objetos?: Conceptos como encapsulamiento, interfaces, reusabilidad pueden seguir siendo útiles, pero hay que evaluar el impacto positivo, no sea que matemos moscas a cañonazos...

Y ahora una serie de enlaces sobre el mismo tema:

"Orientación a objetos: algunas críticas" en barrapunto

lunes, abril 02, 2007

Entrevistas a gurús de la programación paralela

En el estupendo blog Thinking Parallel, se ha comenzado una serie muy prometedora, entrevistas a gurús de la programación paralela, gente que ha diseñado sistemas que la soportan, la facilitan y/o la potencian: Joe Armstrong de Erlang, William Gropp de MPI, Sanjiv Shah de OpenMP, David Butenhof de los threads POSIX (de quien ya se ha hablado por aquí en Diseño sencillo contra implementación correcta) Además promete intentar entrevistar a los responsables de los threads de la JVM y del .NET framework. Las entrevistas son por correo y tienen la particularidad de que son las mismas para todos ellos, cinco preguntas sobre el la programación paralela en general y cinco preguntas sobre su sistema en particular.

De momento ha publicado ya dos, muy interesantes: Ten Questions with Joe Armstrong about Parallel Programming and Erlang y Ten Questions with William Gropp about Parallel Programming and MPI.
Actualización: Se ha publicado la tercera entrega: Ten Questions with Sanjiv Shah about Parallel Programming and OpenMP

Extractando. Joe Armstrong:

  • Sobre balas de plata: Si, las infraestructuras puras de paso de mensajes resolverán muchos problemas (cosas como el servicio de cola simple de amazon(?)). Es una vuelta a la programación basada en flujo de Paul Morisson
  • Comparando la programación paralela con la secuencial: No es más difícil - es difícil debido al modelo dominante de bloqueos, threads y memoria compartida, que si es dificil. Los sistemas puros de paso de mensajes son más fáciles de programar y de comprender
William Gropp (más pragmático al parecer):
  • Sobre mensajes contra memoria compartida: Ambas tienen virtudes y defectos. El paso de mensajes traspapasa la gestión de las estructuras de datos distribuidas al programador. La memoria compartida requiere un gran cuidado para evitar condiciones de carrera y bugs de rendimiento (como la falsa compartición). Ninguno es un modelo de programación completo. Hemos tenido y seguiremos teniendo acaloradas discusiones(*) sobre las deficiencias de ambos.
(*)también conocidas como flames :)

Actualización: Sanjiv Shah:
  • Ahondando más en el tema de paso de mensajes contra memoria compartida:Decidir cual es apropiada depende muchísimo de la aplicación: la memoria compartida facilita unas cosas y la memoria distribuida otras. SETI@home es ahora el ejemplo clásico: apenas se comparten estados entre todos los ordenadores que están ejecutándose a lo largo del mundo independientemente. Muchas aplicaciones de este estilo usan memoria distribuida de modo natural. Por otra parte cuando hay muchos cambios de estado que se deben compartir, el uso de memoria compartida tiene mucho sentido.


Entrevistas a gurús de la programación paralela en barrapunto

miércoles, marzo 28, 2007

VLC se pasa a Qt

Leo a través de una noticia sobre el reproductor multimedia VLC en OSNews, VLC: Beyond the Basics, que VLC va a dejar de usar wxWidgets para pasarse a Qt. Las razones que se aducen para el cambio son sobre todo de localización: problemas con lenguajes escritos de derecha a izquierda y problemas con unicode, aunque otra razón es para probar algo nuevo :) La elección ha sido Qt. Como comenta el desarrollador de VLC tema da para muchísimos flames, pero ¿Que librería de interfaces gráficos de usuario multiplataforma usas? ¿Por qué?

VLC se pasa a Qt en barrapunto

martes, marzo 20, 2007

Copiar, pegar y código de producción

Hay veces que se juntan varias notas que lees por diversos sitios y te llevan al mismo lugar, al lugar en donde has llegado antes por tus propios medios...

En esta ocasión la moraleja es es Cuidado con el código que cortas/pegas de por ahí. Ya sé, es de lógica, de sentido común pero hay veces que la cosa es bastante sutil. Hay muchos motivos por los que analizarlo, pero entre otros:

  • Puede ser código peligroso: Me acabo de encontrar con un ejemplo de código de "ayuda" en un grupo de noticias a través de Reflections on Trusting Example Code en donde se hace la pregunta ¿habrá muchos problemas de seguridad en código posteado por internet?
  • Puede ser código simplificado: En exampleCode != productionCode se habla de código copiado directamente del ejemplo de los libros y la diferencia con un código eficiente y mantenible.
  • Puede hacer asunciones peligrosas: Hace poco buscando ejemplos de uso de criptografía en .NET, para codificar y decodificar con AES concretamente, casi todos los ejemplos usaban PasswordDeriveBytes que tanto en la MSDN como en la documentación de mono: PasswordDeriveBytes dicen que es obsoleta y que produce problemas de interoperabilidad (no usa un algoritmo estándar) Para el framework 2.0 por cierto existe Rfc2898DeriveBytes.GetBytes que no tiene ese problema, porque, este si, usa un algoritmo estándar, PBKDF2 con HMACSHA1. Lo que asumía el código de ejemplo es que no nos importaba la interoperabilidad ni los estándares, cosa que en este caso por supuesto no es cierta ;)
En fín, que el mantra que me voy a repetir hoy es Trata el código de los demás como si fuese tuyo: debe pasar por la misma evaluación de tecnologías, los mismos test, por el mismo control de calidad, como mínimo...



Copiar, pegar y código de producción en Barrapunto

martes, marzo 13, 2007

POO, el código como diseño, y más cosas



POO, el código como diseño, y más cosas en Barrapunto