Ruby: configuración del entorno de desarrollo

traducido por I. A.

Ruby es un lenguaje de programación bien establecido desde hace muchos años y también puede recomendarse a los principiantes. Ruby sigue el paradigma orientado a objetos y contiene muchos conceptos que soportan bien la programación orientada a objetos. Además, el framework Ruby on Rails facilita mucho el desarrollo de aplicaciones web complejas.

El obstáculo más difícil de superar cuando se empieza con Ruby es la instalación de todo el entorno de desarrollo. Por esta razón, he escrito este breve tutorial sobre cómo empezar con Ruby. Así que vamos a empezar con la instalación de inmediato.

Mi sistema operativo es un Linux Debian 12 y Ruby se puede instalar muy fácilmente con el comando sudo apt-get install ruby-full. Este procedimiento se puede aplicar a todas las distribuciones de Linux basadas en Debian, como Ubuntu. A continuación, puede utilizar ruby -v para comprobar el éxito en el bash.

ruby -v
ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) [x86_64-linux-gnu]
Bash

Si ahora seguimos el tutorial de la página principal de Ruby on Rails y queremos instalar el framework Rails mediante gem rails, ya nos encontramos con el primer problema. No se pueden instalar las librerías para Ruby porque faltan autorizaciones. Ahora se nos ocurre instalar las librerías como superusuario con sudo. Desafortunadamente, esta solución es sólo temporal e impide que las bibliotecas se encuentren correctamente más tarde en el entorno de desarrollo. Es mejor crear una carpeta para los GEMs en el directorio home del usuario y hacer que esté disponible a través de una variable de sistema.

export GEM_HOME=/home/<user>/.ruby-gems

export PATH=$PATH:/home/<user>/.ruby-gems

La línea anterior debe introducirse al final del archivo .bashrc para que los cambios permanezcan. Es importante que se sustituya <user> por el nombre de usuario correcto. El éxito de esta acción se puede comprobar a gem environment y debe dar lugar a una salida similar a la siguiente.

ed@:~$ gem environment
RubyGems Environment:
  - RUBYGEMS VERSION: 3.3.15
  - RUBY VERSION: 3.1.2 (2022-04-12 patchlevel 20) [x86_64-linux-gnu]
  - INSTALLATION DIRECTORY: /home/ed/.ruby-gems
  - USER INSTALLATION DIRECTORY: /home/ed/.local/share/gem/ruby/3.1.0
  - RUBY EXECUTABLE: /usr/bin/ruby3.1
  - GIT EXECUTABLE: /usr/bin/git
  - EXECUTABLE DIRECTORY: /home/ed/Programs/gem-repository/bin
  - SPEC CACHE DIRECTORY: /home/ed/.local/share/gem/specs
  - SYSTEM CONFIGURATION DIRECTORY: /etc
  - RUBYGEMS PLATFORMS:
     - ruby
     - x86_64-linux
  - GEM PATHS:
     - /home/ed/Programs/gem-repository
     - /home/ed/.local/share/gem/ruby/3.1.0
     - /var/lib/gems/3.1.0
     - /usr/local/lib/ruby/gems/3.1.0
     - /usr/lib/ruby/gems/3.1.0
     - /usr/lib/x86_64-linux-gnu/ruby/gems/3.1.0
     - /usr/share/rubygems-integration/3.1.0
     - /usr/share/rubygems-integration/all
     - /usr/lib/x86_64-linux-gnu/rubygems-integration/3.1.0
  - GEM CONFIGURATION:
     - :update_sources => true
     - :verbose => true
     - :backtrace => false
     - :bulk_threshold => 1000
  - REMOTE SOURCES:
     - https://rubygems.org/
  - SHELL PATH:
     - /home/ed/.local/bin
     - /usr/local/bin
     - /usr/bin
     - /bin
     - /usr/local/games
     - /usr/games
     - /snap/bin
     - /home/ed/Programs/maven/bin
     - /usr/share/openjfx/lib
- /home/ed/.local/bin
Bash

Con esta configuración, los GEM de Ruby ya se pueden instalar sin dificultad. Vamos a probarlo ahora mismo e instalar el framework Ruby on Rails, que nos ayuda en el desarrollo de aplicaciones web: gem install rails. Esto debería ejecutarse sin mensajes de error y con el comando rails -v podemos ver si hemos tenido éxito.

En el siguiente paso podemos crear un nuevo proyecto Rails. Aquí utilizo el ejemplo de la documentación de Ruby on Rails y escribo en bash: rails new blog. Esto crea un directorio llamado blog con los archivos del proyecto. Después de haber cambiado al directorio, todavía tenemos que instalar todas las dependencias. Esto se hace mediante: bundle install.

Aquí nos encontramos con otro problema. La instalación no puede completarse porque parece haber un problema con la biblioteca psych. El verdadero problema, sin embargo, es que no hay soporte para archivos YAML a nivel de sistema operativo. Esto se puede arreglar muy rápidamente instalando el paquete YAML.

sudo apt-get install libyaml-dev

El problema con psych en Ruby on Rails ha existido durante un tiempo y se ha solucionado con la instalación de YAML, de modo que el comando bundle install ahora también se ejecuta correctamente. Ahora también podemos iniciar el servidor para la aplicación Rails: bin/rails server.

ed@:~/blog$ bin/rails server
=> Booting Puma
=> Rails 7.1.3.3 application starting in development 
=> Run `bin/rails server --help` for more startup options
Puma starting in single mode...
* Puma version: 6.4.2 (ruby 3.1.2-p20) ("The Eagle of Durango")
*  Min threads: 5
*  Max threads: 5
*  Environment: development
*          PID: 12316
* Listening on http://127.0.0.1:3000
* Listening on http://[::1]:3000
Use Ctrl-C to stop
Bash

Si ahora llamamos a la URL http://127.0.0.1:3000 en el navegador web, veremos nuestra aplicación web Rails.

Con estos pasos, ya hemos creado un entorno Ruby funcional en nuestro sistema. Ahora es el momento de decidir un entorno de desarrollo adecuado. Si sólo se adaptan ocasionalmente algunos scripts, VIM y Sublime Text son suficientes como editores. Para proyectos de software complejos, se debe utilizar un IDE completo, ya que simplifica el trabajo considerablemente. La mejor recomendación es el IDE de pago RubyMine de JetBrains. Si apoyas proyectos Ruby de código abierto como desarrollador, puedes solicitar una licencia gratuita.

Un IDE para Ruby disponible gratuitamente es VSCode de Microsoft. Sin embargo, primero hay que integrar algunos plugins y VSCode no es muy intuitivo para mi gusto. La integración de Ruby para los IDEs clásicos de Java, Eclipse y NetBeans, está bastante desfasada y sólo puede hacerse funcionar con mucho esfuerzo.

Con esto ya hemos tratado todos los puntos importantes que son necesarios para configurar un entorno Ruby que funcione en tu propio sistema. Espero que este pequeño taller haya reducido significativamente la barrera de entrada al aprendizaje de Ruby. Si te ha gustado este artículo, por favor, dale a me gusta y recomiéndalo a tus amigos.

Entendiendo Linux: redescubrimiento del placer de la tecnología

traducido por I. A.

Desde Windows 10 los usuarios pierden cada vez más control sobre sus sistemas. La palabra clave es la gobernanza donde las empresas tratan de educar a sus usuarios. No te preocupes no voy a dar un gran discurso sobre el libre albedrío y el mal las empresas de tecnología. En este artículo te doy la oportunidad de recuperar el control de tu dispositivo informático. Despídete de Microsoft y Windows y comienza tu viaje con Linux.

Allá por el año 2015 tomé la decisión de deshacerme de Microsoft windows y pasarme al 100% a Linux. Ya tenía en ese momento varias experiencias con Linux en el lado del servidor. Pero usar Linux a diario en el escritorio para todas las tareas era un nuevo reto, porque las cosas son diferentes. Así que pasé alrededor de 4 semanas y varios intentos para encontrar una distribución de Linux de escritorio que mejor se adapte a mis necesidades. Las cosas a las que tienes que prestar atención para obtener el mejor resultado para ti son la disponibilidad de un enorme repositorio de software donde puedas conseguir todas las aplicaciones que necesites. Otro punto importante es el aspecto de tu escritorio. Aquí también hay varias opciones entre las que puedes elegir. Antes de dar una breve visión general sobre las distribuciones y los escritorios, explicaré el problema de las versiones de software y los repositorios.

Un repositorio de software no es más que un gran almacén donde se encuentran los binarios y los instaladores de su aplicación. Si te decides por una distribución y una versión específica tienes un repositorio definido donde puedes comprar las actualizaciones de tu software y distribución. Supongamos que tenemos una distribución Linux con una versión de 2019. El soporte para esta versión es, digamos, hasta 2020. Eso significa que para el repositorio de software el software incluido sólo contiene un estado de este tiempo. Si desea tener para esta distribución la versión más reciente de GIMP como la 2.10.36 de noviembre de 2023 no podrá obtenerla del repositorio de su distribución original. La última versión de software para GIMP en el repositorio original es la versión de 2020. El mismo problema se da con versiones de software más antiguas. Este es un problema muy específico para los desarrolladores de software y lenguajes de programación disponibles. Si necesitas mantener aplicaciones PHP o JAVA antiguas necesitas compiladores e intérpretes muy específicos que pueden no estar incluidos en tu repositorio de software. Para resolver este problema existen varias soluciones. Los desarrolladores, por ejemplo, pueden utilizar Docker. Como usuario normal puedes intentar conseguir versiones más antiguas o más nuevas de un software directamente del desarrollador / fabricante. Con este conocimiento ahora podemos aprender lo que es una distribución y cuáles existen.

Si quieres elegir para ti una distribución Linux o, abreviado, Distro, tienes una enorme selección donde elegir. ¿Pero qué es una distribución? En general se puede decir que un fabricante junta un Kernel Linux, una colección de software y un repositorio y decora todo con su propio look and feel. También es posible que crees tu propio Linux, incluyendo la compilación de tu propio kernel. Pero Linux no es en todos los casos Linux. Debemos distinguir entre Linux y Unix. Linux es una derivación de Unix, como ya sugiere el nombre LinUx, una combinación de Linus y Unix. La gran diferencia entre Linux y Unix son las funcionalidades de red, que en Unix son más avanzadas. El sistema operativo (OS) de Apple, por ejemplo, está basado en Unix. Un SO Unix muy común es FreeBSD. BSD significa Barkley Software Distribution y es desarrollado continuamente por la Universidad de Barkley en California.

5
Rate your favorite Linux Distribution

Al lado de esto distinguen existen ramas principales de Linux del árbol que también incluyen más derivación. La primera es la alemana Suse con el gestor de paquetes YAST para sus repositorios de software. Por cierto Suse 7.2 fue mi primera prueba de escritorio en 2002. Suse no es tan común y, a veces es muy difícil de encontrar para preguntas especiales o problemas de contenido suficiente. Otra distribución viene de Red Hat, un pionero del código abierto. RHEL o Red Hat Enterprise Linux es una distribución comercial de Linux para servidores. La razón de un Linux comercial se basa en la existencia de sistemas productivos para servidores. Con una licencia RHEL las empresas obtienen de Red Hat un soporte profesional en caso de emergencias. Red Hat Desktop ya no recibe soporte y se ha transformado en Fedora Linux. El gestor de paquetes por defecto para sus repositorios de software es YUM. La última pero no menos importante rama de las principales distribuciones de Linux es Debian, con un gran número de sub-distribuciones. Todas esas populares Distros para principiantes como Linux Mint, Ubuntu o Zorin OS se basan en Debian. Cuando cambié en 2015 a Linux Desktop empecé con Ubuntu Mate LTS y desde finales de 2023 cambié a Debian 12 con un Gnome 3 Desktop. El gestor de paquetes por defecto de los sistemas Debian es APT. Ubuntu introdujo en 2023 su propio gestor de paquetes SNAP.

Otro término importante en el universo Linux es el gestor de escritorio. Aquí puedes elegir entre: KDE, Gnome, Mate, XFCE y Cinnamon. Al igual que mi lista de Distros la lista de Dektops disponibles tampoco está completa. Sólo menciono los más comunes. La mayoría de las Distros Linux vienen con varios gestores de Escritorio por defecto. Usted puede elegir durante el procedimiento de inicio de sesión que Dektop desea utilizar. Así tienes una manera fácil de probar que Escritorio se adapta mejor a ti. Más tarde, cuando tengas más experiencia y ya hayas elegido tu escritorio para tu trabajo diario, puedes deseleccionar los escritorios no deseados durante el proceso de instalación para ahorrar un poco de espacio en disco.

Mucha gente recomienda a los nuevos usuarios de Linux una distribución Ubuntu con el argumento de que es más fácil para los principiantes. Ellos dan golpes como que se puede cambiar a Debian más tarde cuando se tiene más experiencia. Yo tengo una opinión completamente diferente. La complicacion en Linux no es el Distro es el Dektop. Ubuntu / Debian tienen una muy buena comunidad y documentación. Si necesitas solucionar un problema encontrarás ayuda. Por eso es importante saber en que familia se basa tu Distro, para buscar ayuda. Antes de empezar con cosas como multi o dual boot. Crea tu propia máquina virtual con el Linux que deseas probar. Así aprenderás algo sobre el proceso de instalación y el sistema de archivos.

Lo más difícil al principio de mis aventuras en Linux era entender dónde se almacenaban las cosas. Por ejemplo, el software de terceros normalmente se instala en el directorio opt. Complicado es también el sistema de permisos para archivos y directorios en ext3 / ext4. Este concepto no existe en el sistema de archivos FAT o NTFS de Windows. No te preocupes por eso. Durante tu trabajo diario te darás cuenta muy rápido de cómo va.

Microsoft Surface 3 PRO con Ubuntu

Cuando até la primera vez Ubuntu fue alrededor de 2010 donde canonical el distribuidor de Ubuntu introdujo por defecto el Escritorio UNITY. No me gusto porque contiene mucha publicidad y Apps no deseadas como Spotify y Facebook. Me enteré que Ubuntu tiene una Versión con un Clon de Gnome Dektop llamado Mate. Decidí probar y me gustó desde el primer momento. Después de la primera Instalación en mi Laptop en 2015 me fue necesario hasta 2023 solo 2 veces instalar Ubuntu nuevo en mi sistema. Las razones fueron que reemplacé mi SSD interno primero a 1 TB más tarde a 2TB. No hay problemas que los sistemas más lento o el disco en mal estado con archivos huérfanos. No hay limpieza regular y tareas de servicio como son comunes en las ventanas. El sistema simplemente funcionaba estable sin fallos graves. Tampoco tuve ningún problema con los controladores de hardware. AL mis nuevos componentes siempre fueron detectados correctamente desde linux y a menudo existen pequeñas herramientas de administración. Stremdeck UI o Noson para Sonos Speaker por ejemplo. Cuando conseguí mi nuevo portátil en diciembre de 2023 decidí pasar de Ubuntu al original. Porque Ubuntu está hecho por una empresa y a menudo deciden seguir su propio camino. Quién sabe si en el futuro se transforman a un comportamiento de Microsoft. Prefiero siempre hacer mi transición temprano sin presión para estar preparado antes de que no tengo otra opción.

Por supuesto que uso un Antivirus y un Firewall en mi sistema. Porque Linux no está libre contra los malos ataques, así que también hay necesidades de protección.

Mucha gente se equivoca al cambiar de Microsoft Office a Libre Office. El verdadero secreto para no perder el diseño es tener cuidado con las fuentes. Cuando tus documentos originales de MS Office usan las fuentes por defecto de Microsoft, necesitas instalarlas también en tu máquina Linux para no destruir el diseño de los documentos de Office.

Para mi no hay necesidad de volver a Windows. Bueno, yo no soy un jugador, pero también para este existen muchas soluciones. Steam también está disponible en Linux. La mayoría de las personas que conozco ya ni siquiera juegan en PC o portátiles, prefieren consolas como PlayStation. Para mi Linux es genial porque tengo control total sobre mi sistema, es gratis y puedo personalizarlo como quiera. Si tienes un viejo portátil que ya no funciona con Windows, prueba a instalar Linux y disfruta.

Adiós privacidad, adiós libertad

Cuanto más tengamos que repetir lo buena que es nuestra libertad de interlocución, menos podremos...

Entendiendo Linux: redescubrimiento del placer de la tecnología

Es hora de volver a tomar el control de tu hardware, porque no es necesario...

Trabajar con archivos de texto en el shell de Linux

La línea de comandos es una poderosa herramienta en Linux. En este artículo, usted aprenderá...

Trabajar con archivos de texto en el shell de Linux

Linux se convierte cada vez más en un sistema operativo popular para los profesionales de TI. Una de las razones de este movimiento son las soluciones de servidor. La estabilidad y el bajo consumo de recursos son algunas de las características importantes para esta elección. Si ya ha jugado con un servidor Microsoft, echará de menos el escritorio gráfico de un servidor Linux. Después de un inicio de sesión en un servidor Linux sólo se ve el símbolo del sistema está a la espera de sus entradas.

En este breve artículo te presento algunos programas útiles de Linux para trabajar con archivos en la línea de comandos. Esto te permite recopilar información, por ejemplo, de archivos de registro. Antes de empezar me gustaría recomendarte un sencillo y potente editor llamado joe.

Ctrl + C – Abortar la edición actual de un fichero sin guardar los cambios
Ctrl + KX – Salir de la edición actual y guardar el archivo
Ctrl + KF – Buscar texto en el archivo actual
Ctrl + V – Pegar el portapapeles en el documento (CMD + V para Mac)
Ctrl + Y – Borrar la línea actual donde está el cursor

Para instalar joe en una distribución Linux basada en Debian basta con teclear:

1. Cuando necesite encontrar contenido en un archivo de texto enorme, GREP será su mejor amigo. GREP le permite buscar patrones de texto en archivos.

gerp <pattern> file.log
    -n : number of lines that matches
    -i : case insensitive
    -v : invert matches
    -E : extended regex
    -c : count number of matches
    -l : find filenames that matches the pattern
Bash

2. Cuando necesite analizar paquetes de red, NGREP es la herramienta que necesita.

ngrep -I file.pcap
    -d : specify the network interface
    -i : case insensitive
    -x : print in alternate hexdump
    -t : print timestamp
    -I : read a pcap file
Bash

3. Cuando necesite ver los cambios entre dos versiones de un archivo, DIFF hará el trabajo.

diff version1.txt version2.txt
    -a : add
    -c : change
    -d : delete
     # : line numbers
     < : file 1
     > : file 2
Bash

4. A veces es necesario dar un orden a las entradas de un fichero. SORT le ayudará en esta tarea.

sort file.log 
     -o : write the result to a file
     -r : reverse order
     -n : numerical sort
     -k : sort by column
     -c : check if orderd
     -u : sort and remove
     -f : ignore case
     -h : human sort
Bash

5. Si tienes que reemplazar cadenas dentro de un texto enorme, como buscar y reemplazar, puedes hacerlo con SED, el editor de secuencias.

sed s/regex/replace/g
     -s : search
     -g : replace
     -d : delete
     -w : append to file
     -e : execute command
     -n : suppress output
Bash

6. El análisis sintáctico de campos con delimitadores en archivos de texto puede realizarse mediante CUT.

cut -d ":" -f 2 file.log
     -d : use the field delimiter
     -f : field numbers
     -c : specific characters position
Bash

7. La extracción de subcadenas que aparecen una sola vez en un fichero de texto se consigue con UNIQ.

uniq file.txt
     -c : count the numbers of duplicates
     -d : print duplicates
     -i : case insesitive
Bash

8.  AWK es un lenguaje de programación considerado para manipular datos.

awk {print $2} file.log
Bash

Adiós privacidad, adiós libertad

Cuanto más tengamos que repetir lo buena que es nuestra libertad de interlocución, menos podremos...

Entendiendo Linux: redescubrimiento del placer de la tecnología

Es hora de volver a tomar el control de tu hardware, porque no es necesario...

Trabajar con archivos de texto en el shell de Linux

La línea de comandos es una poderosa herramienta en Linux. En este artículo, usted aprenderá...

Primero la prueba?

traducido por I. A.

java Aktuell 2024.03

Cuando empecé con la programación dirigida por pruebas hace más de 10 años, conocía muchos conceptos diferentes en teoría. Pero este enfoque de escribir primero los casos de prueba y luego implementarlos no era, de alguna manera, la forma con la que me llevaba bien. Para ser honesto, este sigue siendo el caso hoy en día. Así que encontré una adaptación del paradigma TDD de Kent Beck que me funciona. Pero lo primero es lo primero. Quizás mi enfoque también sea bastante útil para unos u otros.

Originalmente provengo de entornos para aplicaciones web altamente escalables a las que todas las grandes teorías de la universidad no pueden aplicarse fácilmente en la práctica. La razón principal es la gran complejidad de dichas aplicaciones. Por un lado, varios sistemas adicionales como la caché en memoria, la base de datos y la gestión de identidades y accesos (IAM) forman parte del sistema global. Por otro lado, muchos marcos modernos como OR Mapper ocultan la complejidad tras diferentes capas de acceso. Como desarrolladores, necesitamos dominar todas estas cosas. Por eso existen soluciones robustas y probadas en la práctica que son bien conocidas pero que rara vez se utilizan. Kent Beck es una de las voces más importantes a favor del uso práctico de las pruebas automatizadas de software.

Si queremos involucrarnos en el concepto de TDD, es importante no dar demasiada importancia a cada personaje. No todo está escrito en piedra. Lo importante es el resultado al final del día. Por ello, es esencial tener presente el objetivo de todos los esfuerzos para lograr un valor añadido personal. Así que empecemos por ver qué queremos conseguir en primer lugar.

El éxito nos da la razón

Cuando empecé como desarrollador, necesitaba un feedback constante sobre si lo que estaba montando funcionaba realmente. La mayoría de las veces generaba esta retroalimentación esparciendo durante mi implementación innumerables salidas de consola, por un lado, y por el otro siempre intentaba integrar todo en una interfaz de usuario y luego ‘hacer clic’ manualmente. Básicamente una configuración de prueba muy engorrosa, que luego tiene que ser eliminada de nuevo al final. Si más tarde había que hacer correcciones de errores, todo el procedimiento comenzaba de nuevo. Todo resultaba en cierto modo insatisfactorio y muy alejado de una forma productiva de trabajar. Había que mejorar esto de alguna manera sin tener que reinventarse cada vez.

Por último, mi enfoque original tiene exactamente dos puntos débiles importantes. El más obvio es la entrada y salida de información de depuración a través de la consola.

Pero el segundo punto es mucho más grave. Porque todo el conocimiento adquirido sobre esta implementación en particular no se conserva. Por lo tanto, corre el riesgo de desvanecerse con el tiempo y, en última instancia, perderse. Sin embargo, estos conocimientos especializados son muy valiosos para muchas fases posteriores del proceso de desarrollo de software. Con esto me refiero explícitamente al tema de la calidad. La refactorización, las revisiones de código, las correcciones de errores y las solicitudes de cambio son sólo algunos de los posibles ejemplos en los que se requieren conocimientos detallados en profundidad.

Personalmente, el trabajo monótono y repetitivo me cansa rápidamente y me gustaría evitarlo. Pasar una y otra vez por una aplicación con el mismo procedimiento de prueba está muy lejos de lo que para mí constituye una jornada laboral satisfactoria. Quiero descubrir cosas nuevas. Pero sólo puedo hacerlo si no estoy atrapado en el pasado.

Conference Talk

Pero se atreven a hacer algo

Pero antes de entrar en cómo he condimentado mi trabajo diario de desarrollo con TDD, tengo que decir unas palabras sobre la responsabilidad y la valentía. En conversaciones, otras personas me han dicho con frecuencia que tengo razón, pero que no pueden tomar medidas para seguir mis recomendaciones porque el jefe de proyecto o algún otro superior no da luz verde.

Esa actitud me parece muy poco profesional. No le pregunto a un director de marketing qué algoritmo termina siendo el mejor. Simplemente no tiene ni idea de lo que estoy hablando, porque no es su área de responsabilidad. Un jefe de proyecto que hable en contra del trabajo basado en pruebas en el equipo de desarrollo también ha perdido su trabajo. Hoy en día, los marcos de pruebas están tan bien integrados en el entorno de compilación que incluso las personas sin experiencia pueden preparar TDD en cuestión de momentos. Por lo tanto, no es necesario darle demasiada importancia. Puedo prometer que incluso los primeros intentos no llevarán más tiempo que con el enfoque original. Al contrario, habrá un notable aumento de la productividad muy rápidamente.

La primera etapa de la evolución

Como ya he mencionado, el registro es una parte central del desarrollo basado en pruebas para mí. Siempre que tiene sentido, intento mostrar el estado de los objetos o variables en la consola. Si utilizamos los medios que nos proporciona el lenguaje de programación empleado para ello, esto significa que al menos debemos comentar esta salida del sistema una vez realizado el trabajo y volver a comentarla más tarde cuando busquemos errores. Un procedimiento redundante y propenso a errores.

Si, por el contrario, utilizamos un marco de logging desde el principio, podemos dejar tranquilamente la información de depuración en el código y desactivarla más tarde en el funcionamiento productivo mediante la configuración del nivel de log.

También utilizo el logging como trazador. Esto significa que cada constructor de una clase escribe una entrada de registro correspondiente por la información de nivel de registro mientras está siendo llamado. Esto me permite ver el orden en que se instancian los objetos. De vez en cuando también me he dado cuenta de la instanciación excesivamente frecuente de un mismo objeto. Esto es útil para las medidas de rendimiento y optimización de memoria.

Registro los errores que se lanzan durante el manejo de excepciones como errores o advertencias, dependiendo del contexto. Esta es una herramienta muy útil para localizar errores más adelante en la operación.

Así que si tengo un acceso a la base de datos, escribo una salida de registro en la depuración de nivel de registro como el SQL asociado fue montado. Si este SQL conduce a una excepción porque contiene un error, esta excepción se escribe con el error de nivel de registro. Si, por el contrario, se realiza una simple consulta de búsqueda con una sintaxis SQL correcta y el conjunto de resultados está vacío, este evento se clasifica como Debug o Warning, en función de las necesidades. Por ejemplo, si se trata de una solicitud de inicio de sesión con un nombre de usuario o una contraseña incorrectos, suelo optar por el nivel de registro Advertencia, ya que puede contener aspectos relacionados con la seguridad durante el funcionamiento.

En el contexto general, tiendo a configurar el registro para la ejecución del caso de prueba de forma muy locuaz y me limito a una salida de consola pura. Durante el funcionamiento, la información de registro se escribe en un archivo de registro.

El huevo o la gallina

Una vez que hemos sentado las bases para un bucle de retroalimentación adicional con el registro, el siguiente paso es decidir qué hacer a continuación. Como ya he mencionado, me resulta muy difícil escribir primero un caso de prueba y luego encontrar una implementación adecuada para él. Muchos otros desarrolladores que empiezan con TDD también se enfrentan a este problema.

Una cosa que ya puedo anticipar es el problema de asegurarse de que una implementación es comprobable. Una vez que tengo el caso de prueba, inmediatamente me doy cuenta de si lo que estoy creando es realmente comprobable. Los desarrolladores TDD experimentados han aprendido rápidamente en carne y hueso cómo debe ser el código comprobable. El punto más importante aquí es que los métodos siempre deben tener un valor de retorno que preferiblemente no sea nulo. Esto se puede conseguir, por ejemplo, devolviendo una lista vacía en lugar de null.

El requisito de tener un valor de retorno se debe a la forma en que funcionan los marcos de pruebas unitarias. Un caso de prueba compara el valor de retorno de un método con un valor esperado. La aserción de prueba tiene diferentes características y por lo tanto puede ser: igual, desigual, verdadero o falso. Por supuesto, aquí también hay diferentes variaciones. Por ejemplo, es posible probar métodos que no tienen valor de retorno utilizando excepciones. Todos estos detalles se aclaran en muy poco tiempo durante el uso de TDD. De modo que todo el mundo puede empezar inmediatamente sin largas preparaciones.

Al leer el libro Test Driven Development by Example de Kent Beck, también encontramos rápidamente una explicación de por qué los casos de prueba deben escribirse primero. Se trata de un factor psicológico. Debería ayudarnos a sobrellevar mejor el estrés habitual que surge en el proyecto. Crea en nosotros un estado mental sobre el estado y el progreso del trabajo actual. Nos guía en un proceso iterativo para ampliar y mejorar paso a paso la solución existente a través de los distintos casos de prueba.

Para quienes, como yo, no tienen una idea concreta del resultado final al inicio de una aplicación, este enfoque es difícil de aplicar. El efecto previsto de relajación se convierte en negativo. Como todos los seres humanos somos diferentes, tenemos que averiguar qué es lo que nos hace funcionar para conseguir el mejor resultado posible. Lo mismo ocurre con las estrategias de aprendizaje. Algunas personas procesan mejor la información visualmente, otras de forma más háptica y otras extraen todo lo importante de las palabras habladas. Así que intentemos no doblegarnos contra nuestra naturaleza para producir resultados mediocres o pobres.

Trazar la primera línea

Un tema sólo se me aclara mientras trabajo en él. Así que pruebo a ponerlo en práctica hasta que necesito un primer feedback. Es entonces cuando escribo la primera prueba. Este enfoque da lugar automáticamente a preguntas, cada una de las cuales merece su propio caso de prueba. ¿Puedo encontrar todos los resultados disponibles? ¿Qué ocurre si el conjunto de resultados está vacío? ¿Cómo se puede reducir el conjunto de resultados? Todas estas cuestiones pueden anotarse en un papel y marcarse paso a paso. La idea de anotar en un papel una lista de tareas pendientes la tuve mucho antes de que apareciera en el libro de Kent Beck mencionado anteriormente. Me ayuda a conservar pensamientos rápidos sin distraerme de lo que estoy haciendo en ese momento. También me da una sensación de logro al final del día.

Dado que no espero hasta que he implementado todo para escribir la primera prueba, este enfoque también da lugar a un enfoque iterativo. También me doy cuenta muy rápidamente si mi diseño no es suficientemente comprobable, ya que recibo feedback inmediato. Esto da lugar a mi propia interpretación de TDD, que se caracteriza por el cambio permanente entre la implementación y la escritura de pruebas.

Como resultado de mis primeros intentos de TDD, ya noté una aceleración de mis métodos de trabajo en la primera semana. También adquirí más confianza. Pero mi forma de programar también empezó a cambiar muy pronto. He notado que mi código se ha vuelto más compacto y robusto. Cosas que sólo se habían hecho evidentes con el tiempo surgieron durante actividades como la refactorización y las ampliaciones. Los casos de prueba fallidos me han salvado de sorpresas desagradables.

Empezar sin exceso de celo

Si decidimos utilizar TDD en un proyecto existente, es una mala idea empezar a escribir casos de prueba para la funcionalidad existente. Aparte del tiempo que hay que planificar para ello, el resultado no cumplirá las altas expectativas.

Uno de los problemas es que ahora hay que familiarizarse con cada funcionalidad y esto lleva mucho tiempo. La calidad de los casos de prueba resultantes también es inadecuada. El problema también surge de la falta de experiencia. Cuando se empieza a acumular experiencia, la calidad de los casos de prueba tampoco es óptima y es posible que haya que reescribir el código para que se pueda probar. Esto crea muchos riesgos que son problemáticos para el día a día del proyecto.

Un procedimiento probado para introducir TDD es simplemente utilizarlo para la implementación actual en la que se está trabajando. El estado actual del problema actual se documenta mediante pruebas automatizadas. Como ya estás en territorio conocido, no tienes que familiarizarte con un tema nuevo, así que puedes concentrarte plenamente en formular pruebas significativas. Aparte del hecho de que asumes la responsabilidad del trabajo de otras personas sin que te lo pidan cuando implementas casos de prueba para ellos.

La funcionalidad existente sólo se complementa con casos de prueba cuando se corrigen errores. Para la corrección, hay que ocuparse de todos modos de los detalles de implementación, de modo que aquí se sabe lo suficiente sobre cómo debe comportarse una funcionalidad. Las pruebas resultantes también documentan la corrección y garantizan que el comportamiento no cambie en el futuro durante los trabajos de optimización.

Si sigue este procedimiento de forma disciplinada, no se perderá en la llamada actividad frenética, que a su vez es lo contrario de la productividad. Además, adquirirá rápidamente conocimientos sobre cómo implementar pruebas eficaces y significativas. Sólo cuando se haya adquirido suficiente experiencia y, posiblemente, se planifique una amplia refactorización, podrá plantearse cómo mejorar gradualmente la cobertura de las pruebas para todo el proyecto.

Nivel de calidad

Que haya casos de prueba disponibles no significa que sean significativos. Una cobertura de pruebas elevada tampoco demuestra que un programa no contenga errores. Una cobertura de pruebas alta sólo garantiza que un programa se comporta dentro del ámbito de las pruebas.

Entonces, ¿cómo asegurarse de que las pruebas existentes suponen realmente un enriquecimiento y tienen un buen valor informativo? El primer punto, y en mi opinión el más importante, es que los casos de prueba sean lo más breves posible. En concreto, esto significa que una prueba sólo responde a una pregunta explícita, por ejemplo: ¿Qué ocurre si el conjunto de resultados está vacío? El método de prueba se denomina en función de la pregunta. El valor añadido de este enfoque surge cuando el caso de prueba falla. Si la prueba es muy corta, a menudo es posible saber a partir del método de prueba cuál es el problema sin tener que dedicar mucho tiempo a familiarizarse con un caso de prueba.

Otro punto importante en el procedimiento TDD es comprobar la cobertura de la prueba para las líneas de código, así como para las ramas de mi funcionalidad implementada. Si, por ejemplo, no puedo simular la ocurrencia de una sola condición en una sentencia IF, esta condición se puede eliminar sin dudarlo.

Por supuesto, también tiene bastantes dependencias de bibliotecas externas en su propio proyecto. Ahora puede ocurrir que un método de esta librería lance una excepción que no pueda ser simulada por ningún caso de prueba. Esta es exactamente la razón por la que deberías esforzarte por conseguir una alta cobertura de pruebas, pero no desesperar si no se puede alcanzar el 100%. Especialmente cuando se introduce TDD, una buena medida de cobertura de pruebas superior al 85% es habitual. A medida que el equipo de desarrollo adquiere experiencia, este valor puede incrementarse hasta el 95%.

Por último, sin embargo, hay que tener en cuenta que no hay que dejarse llevar demasiado. Porque puede convertirse rápidamente en excesivo y entonces todas las ventajas obtenidas se pierden rápidamente. La cuestión es que no escribas pruebas que a su vez prueben pruebas. Aquí es donde el gato se muerde la cola. Esto también se aplica a las bibliotecas de terceros. Tampoco se escriben pruebas para ellas. Kent Beck es muy claro al respecto: “Aunque haya buenas razones para desconfiar del código ajeno, no lo pruebes. El código externo requiere más de tu propia lógica de implementación”.

Lecciones aprendidas

Las lecciones que se pueden aprender cuando se intenta conseguir la mayor cobertura de pruebas posible son las que repercutirán en la programación futura. El código se vuelve más compacto y robusto.

La productividad aumenta simplemente porque se evita el trabajo monótono y propenso a errores gracias a la automatización. No hay pasos de trabajo adicionales porque los viejos hábitos se sustituyen por otros nuevos y mejores.

Un efecto que he observado una y otra vez es que cuando miembros individuales del equipo han optado por TDD, sus éxitos se reconocen rápidamente. En pocas semanas, todo el equipo había desarrollado el TDD. Cada uno según sus capacidades. Algunos con Test First, otros como acabo de describir. Al final, lo que cuenta es el resultado y era uniformemente excelente. Cuando el trabajo es más fácil y al final del día cada individuo tiene la sensación de que también ha conseguido algo, esto da al equipo un enorme impulso de motivación, lo que da al proyecto y al ambiente de trabajo un enorme impulso. ¿A qué espera? Pruébelo usted mismo ahora mismo.

No post found

Adiós privacidad, adiós libertad

traducido por I. A.

Los nuevos términos y condiciones de los servicios de Microsoft publicados en octubre de 2023 causaron indignación en el mundo de la informática. El motivo fue un párrafo en el que se afirmaba que todos los servicios de Microsoft se basan ahora en la inteligencia artificial. Se supone que esta inteligencia artificial se utilizará para reconocer las infracciones de los derechos de autor. Esto incluye música, películas, gráficos, libros electrónicos y, por supuesto, software. Si esta inteligencia artificial detecta infracciones de los derechos de autor en el sistema, estos archivos se eliminarán automáticamente del “sistema”. Por el momento no está claro si esta norma se aplica al propio disco duro local del usuario o sólo a los archivos en la nube de Microsoft. Microsoft también ha declarado que los usuarios que infrinjan las normas sobre derechos de autor serán excluidos de todos los servicios de Microsoft en el futuro.

Esta exclusión tiene varios “sabores”. Las primeras preguntas que vienen a la mente son: ¿Qué ocurre con los planes de pago como Skype? ¿Me bloquearán y luego me devolverán el crédito no utilizado? Un escenario aún peor sería que también podría perder todo mi crédito y mis compras digitales, como el acceso a juegos y otras cosas. ¿O no se verán afectadas las suscripciones de pago? Hasta ahora esta parte no está clara.

Si eres usuario de Apple y crees que esto no te afecta, asegúrate de no utilizar un servicio de Microsoft que no sepas que pertenece a Microsoft. No todos los productos llevan el nombre de la empresa. Piénselo, porque quién sabe si estos productos están espiando su sistema. Algunas aplicaciones como Skype, Teams, Edge Browser y Visual Studio Code también están disponibles para otras plataformas como Apple y Linux.

Microsoft también es propietaria de la plataforma de alojamiento de código fuente GitHub y de una red social para especialistas llamada LinkedIn. Con Office 360, puedes utilizar todo el paquete de Microsoft Office a través del navegador web como una solución en la nube y todos tus documentos se almacenan en la nube de Microsoft. La misma nube en la que instituciones gubernamentales estadounidenses como la CIA, la NSA y muchas otras almacenan sus archivos. Parece ser un lugar seguro para todos tus pensamientos escritos en un documento de Office.

Este pequeño detalle sobre los documentos de Office nos lleva a una pequeña nota al margen en los nuevos términos y condiciones de Microsoft. La lucha contra la incitación al odio. Signifique lo que signifique. El insulto público y la difamación siempre han sido tratados estrictamente como un delito penal por la ley. No se trata de un delito trivial castigado con una pequeña multa. Así que no me queda claro qué significa toda esta charla sobre el discurso del odio. Quizá sea un intento de introducir la censura pública de la libertad de expresión.

Pero volvamos a la nota al margen de las condiciones de uso de Microsoft sobre la incitación al odio. Microsoft ha escrito algo como Si se detecta incitación al odio, se advertirá al usuario y, si las infracciones se producen más de una vez, se desactivará la cuenta Microsoft del usuario.

Si crees que esto es sólo algo que está ocurriendo ahora de la mano de Microsoft, ten por seguro que muchas otras empresas están trabajando para introducir servicios equivalentes. La plataforma de comunicaciones Zoom, por ejemplo, también incluye técnicas de Inteligencia Artificial para supervisar las comunicaciones de los usuarios con “fines formativos”.

Con todas estas novedades, hay una gran pregunta que necesita respuesta: ¿Qué puedo hacer yo mismo? La respuesta es sencilla. Abandone el universo digital y vuelva al mundo real. Vuelva a encender su cerebro. Utiliza papel y bolígrafo, paga en efectivo, deja el smartphone en casa y nunca en la mesilla de noche. Si no lo usas, ¡apágalo! Queda con tus amigos físicamente siempre que sea posible y luego no lleves el smartphone. No habrá gobierno, ni presidente, ni mesías que traiga el cambio. Depende de nosotros hacerlo.

No post found

README – cómo saber

traducido por I. A.

Los archivos README tienen una larga tradición en los proyectos de software. Originalmente, estos archivos de texto sin formato contenían información sobre la licencia e instrucciones sobre cómo compilar el artefacto correspondiente a partir del código fuente o notas importantes sobre la instalación del programa. No existe ningún estándar real sobre cómo construir un archivo README de este tipo.

Desde que GitHub (adquirida por Microsoft en 2018) inició su marcha triunfal como plataforma de alojamiento de código libre para proyectos de código abierto, existe desde bastante pronto la función de mostrar el archivo README como página de inicio del repositorio. Todo lo que se necesita es crear un simple archivo de texto llamado README.md en el directorio raíz del repositorio.

Para poder estructurar los archivos README de forma más clara, se buscó una posibilidad de formato simple. Rápidamente se eligió la notación markdown porque es fácil de usar y se puede renderizar de forma bastante eficiente. Esto facilita la lectura de las páginas de resumen y permite utilizarlas como documentación del proyecto.

Es posible enlazar varios archivos markdown como documentación del proyecto. Así se crea una especie de mini WIKI que se incluye en el proyecto y también se versiona a través de Git.

El asunto tuvo tanto éxito que soluciones de autoalojamiento como GitLab o la comercial BitBucket también han adoptado esta función.

Ahora, sin embargo, se plantea la cuestión de qué contenido es mejor escribir en un archivo README de este tipo para que también represente un verdadero valor añadido para los forasteros. Con el paso del tiempo, se han establecido los siguientes puntos:

  • Breve descripción del proyecto
  • Condiciones de uso del código fuente (licencia)
  • Cómo utilizar el proyecto (por ejemplo, instrucciones para compilar o cómo integrar la biblioteca en proyectos propios)
  • Quiénes son los autores del proyecto y cómo se puede contactar con ellos
  • Qué hacer si desea apoyar el proyecto

Mientras tanto, las llamadas insignias (pegatinas) se han hecho muy populares. A menudo hacen referencia a servicios externos, como el servidor gratuito de integración continua TravisCI. Ayudan a evaluar la calidad del proyecto.

También hay varias plantillas para archivos README en GitHub. Sin embargo, tienes que fijarte en las circunstancias reales de tu propio proyecto y juzgar qué información es realmente relevante para los usuarios. Estas plantillas ayudan mucho a averiguar si se ha pasado por alto algún punto.

El hecho de que prácticamente todos los fabricantes de soluciones de servidores de gestión de control de código fuente hayan integrado ya la función de mostrar el archivo README.md como página de inicio del proyecto para el repositorio de código significa que un README.me también es algo útil para los proyectos comerciales.

Aunque la sintaxis para markdown es fácil de aprender, puede ser más conveniente utilizar directamente un editor MARKDOWN para la edición extensiva de este tipo de archivos. Debes asegurarte de que la vista previa también se muestra correctamente y no se ofrece un simple resaltado de sintaxis.

Los enlaces sólo son visibles para los usuarios registrados.

Los enlaces sólo son visibles para los usuarios registrados.

La Ley de Conway

Dado que el diseño elegido en primer lugar casi nunca es el mejor posible, el…

Lo último no siempre es lo mejor

A qué hay que prestar atención en el entorno comercial para que las actualizaciones de…

README – cómo saber

Los archivos README son archivos de texto y están formateados en notación markdown. El portal…

Opciones de automatización en la gestión de la configuración del software

El desarrollo de software ofrece algunas formas extremadamente eficaces de simplificar tareas recurrentes mediante la…

Anti-Pattern de números de versión

En este artículo analizamos algunas de las mejores prácticas para trabajar con números de versión…

La cara oculta de la inteligencia artificial

traducido por I. A.

publicado también en Tealfeed 10/2022

Como técnico, me fascinan enseguida todo tipo de cosas que de alguna manera parpadean y pitan, por muy inútiles que sean. Los aparatos electrónicos me atraen como las polillas a la luz. Desde hace algún tiempo, una nueva generación de juguetes está a disposición de las masas. Aplicaciones de inteligencia artificial, más concretamente redes neuronales artificiales. Las aplicaciones disponibles gratuitamente ya están haciendo cosas notables y es sólo el principio de lo que podría llegar a ser posible en el futuro. Mucha gente aún no se ha dado cuenta del alcance de las aplicaciones basadas en la inteligencia artificial. No es de extrañar, porque lo que está ocurriendo en el sector de la inteligencia artificial cambiará nuestras vidas para siempre. Podemos decir con razón que vivimos en una época que está haciendo historia. Dependerá de nosotros decidir si los cambios que se avecinan serán buenos o se convertirán en una distopía.

Cuando elegí la inteligencia artificial como especialización en mis estudios hace muchos años, la época aún se caracterizaba por los llamados sistemas expertos. Estos sistemas basados en reglas estaban altamente especializados para su dominio y se diseñaban para los correspondientes expertos. Se suponía que el sistema apoyaba al experto en la toma de decisiones. Entretanto, también disponemos del hardware necesario para crear sistemas mucho más generales. Si consideramos aplicaciones como ChatGPT, se basan en redes neuronales, lo que permite una flexibilidad de uso muy elevada. La desventaja, sin embargo, es que nosotros, como desarrolladores, apenas podemos entender qué salida produce una red neuronal para cualquier entrada dada. Una circunstancia que hace que la mayoría de los programadores que conozco adopten una actitud más bien negativa. Porque ya no dominan el algoritmo y sólo pueden actuar según el principio de ensayo y error.

Podcast

Der philosphische Frühschoppen

Künstliche Intelligenz

In den nächsten 30 Minuten befassen wir uns mit philosophischen Fragen wie „Was ist Intelligenz?“ oder „Was bedeutet Lernen?“. Die Antwort auf diese Fragen lässt uns besser verstehen, wo Künstliche Intelligenz heutzutage zum Einsatz kommt, welche Grenzen es gibt und wohin schlussendlich die Reise führt. Continue reading


Folge 1 – GERMAN

Sin embargo, el poder de las redes neuronales es asombroso. Parece que ya ha pasado la época en que uno podía burlarse de las torpes traducciones automáticas asistidas por software. Por experiencia propia, recuerdo lo tedioso que era dejar que el Traductor de Google tradujera una frase razonable del alemán al español. Para obtener un resultado utilizable, puedes usar la opción inglés-español. Alternativamente, si sólo hablas un inglés rudimentario para uso vacacional, podrías formular frases en alemán muy sencillas que al menos fueran correctas en su contenido. El tiempo que se ahorra con los textos traducidos automáticamente es considerable, aunque tengas que corregirlos y ajustar alguna redacción si es necesario.

Por mucho que aprecie poder trabajar con herramientas tan potentes, tenemos que ser conscientes de que también hay un lado negativo. Cuanto más realicemos nuestras tareas cotidianas con herramientas basadas en la inteligencia artificial, más perderemos la capacidad de realizarlas manualmente en el futuro. Para los programadores, esto significa que con el tiempo perderán su capacidad de expresarse en código fuente a través de IDE basados en la inteligencia artificial. Por supuesto, no se trata de un proceso que ocurra de la noche a la mañana, sino que es gradual. Una vez creada esta dependencia, se plantea la cuestión de si las queridas herramientas disponibles seguirán siendo gratuitas o si las suscripciones existentes sufrirán posiblemente un drástico aumento de precio. Después de todo, debería quedarnos claro que las herramientas de uso comercial que mejoran significativamente nuestra productividad no suelen estar disponibles a bajo precio.

También creo que Internet, tal y como estamos acostumbrados hasta ahora, cambiará mucho en el futuro. Muchos de los servicios gratuitos que se han financiado con publicidad desaparecerán a medio plazo. Veamos como ejemplo el servicio StackOverFlow. Una plataforma de conocimiento muy popular entre los círculos de desarrolladores. Si ahora en el futuro la investigación a cuestiones de programación ChatGPT u otras redes neuronales se cuestionan para StackOverFlow el número de visitantes se hunde continuamente. La base de conocimientos a su vez ChatGPT utiliza se basa en datos de foros públicos como StackOverFlow. Así que en un futuro próximo StackOverFlow intentará que su servicio sea inaccesible para las IAs. Sin duda, también podría haber un acuerdo con pagos compensatorios. De modo que se compensen los ingresos publicitarios omitidos. Como técnicos, no necesitamos que nos digan que una oferta como StackOverFlow incurre en costes considerables de funcionamiento y desarrollo. Queda por ver entonces cómo aceptarán los usuarios la oferta en el futuro. Si no se añaden nuevos datos a StackOverFlow, la base de conocimientos de los sistemas de Inteligencia Artificial dejará también de ser interesante. Por tanto, sospecho que hacia 2030 serán sobre todo los contenidos de alta calidad en Internet los que estarán sujetos a una tarifa.

Si nos fijamos en la previsión de la tendencia a medio plazo de la demanda de programadores, llegamos a la pregunta de si será una buena recomendación en el futuro estudiar informática o empezar un aprendizaje como programador. La verdad es que veo aquí un futuro positivo y animaría a cualquiera que vea la formación como una vocación y no como una necesidad para ganarse la vida. En mi opinión, seguiremos necesitando muchas mentes innovadoras. Sólo aquellos que en lugar de ocuparse de fundamentos y conceptos prefieran aprender rápidamente un marco actual para seguir el ritmo de la hifa emergente del mercado, conseguirán sin duda un éxito limitado en el futuro. Sin embargo, ya he hecho estas observaciones antes de la amplia disponibilidad de los sistemas de Inteligencia Artificial. Por lo tanto, estoy firmemente convencido de que la calidad siempre prevalecerá a largo plazo.

Considero una virtud abordar todo tipo de temas de la forma más crítica y atenta posible. No obstante, debo decir que algunos temores al abordar la inteligencia artificial son bastante infundados. Ya han visto algunas de mis posibles visiones del futuro en este artículo. Las afirmaciones de que la I.A. se apoderará un día de nuestro mundo influyendo sutilmente en los usuarios no iniciados para motivarles a actuar son, en mi opinión, pura fantasía para un periodo hasta 2030 y, dado el estado actual de los conocimientos, infundadas. Desde un punto de vista mucho más realista, veo el problema de que si la gente ingeniosa del marketing llena Internet de artículos de calidad inferior generados por la inteligencia artificial para mejorar su posicionamiento en los buscadores y esto, a su vez, se convierte en una nueva cabina de conocimiento de las redes neuronales, la calidad de los futuros textos generados por la inteligencia artificial se reducirá significativamente.

Los sistemas de Inteligencia Artificial disponibles hasta ahora de forma gratuita tienen una diferencia decisiva con respecto a los humanos. Carece de motivación para hacer algo por iniciativa propia. Sólo a través de una petición extrínseca del usuario comienza la I.A. a trabajar en una cuestión. Se vuelve interesante cuando una I.A. se dedica a preguntas seleccionadas por ella misma y además las investiga de forma independiente. En este caso, la probabilidad de que la inteligencia artificial desarrolle rápidamente una conciencia es muy alta. Si una I.A. de este tipo sigue funcionando con un ordenador cuántico de alto rendimiento, no tendremos suficiente tiempo de reacción para reconocer los desarrollos peligrosos e intervenir. Por lo tanto, definitivamente debemos mantener la obra “Los Físicos” creada por Dürrenmatt en nuestra conciencia. Porque de los fantasmas que llamé una vez, posiblemente no vuelva a deshacerme tan rápido.

Básicamente, tengo que admitir que el tema de la Inteligencia Artificial sigue fascinándome y siento mucha curiosidad por los desarrollos futuros. Sin embargo, creo que es importante no cerrar los ojos ante el lado oscuro de la inteligencia artificial e iniciar un discurso objetivo para explotar el potencial existente de esta tecnología de la forma más inofensiva posible.

Adiós privacidad, adiós libertad

Cuanto más tengamos que repetir lo buena que es nuestra libertad de interlocución, menos podremos...

Usos, Pros, Contras y Peligros de la INTELIGENCIA ARTIFICIAL

traducido por I. A. Hablamos de inteligencia artificial, pero ¿qué es en realidad? Es una...

La caja de herramientas digital

Este artículo sólo es visible para Patreons conectados. Con una suscripción a Patreon me ayudas...

Prevención de inyecciones SQL en Java con JPA e Hibernate

publicado original en inglés en DZone 09.2022

Cuando echamos un vistazo al top 10 de vulnerabilidades de OWASP [1], las Inyecciones SQL siguen en una posición popular. En este breve artículo, discutimos varias opciones sobre cómo las Inyecciones SQL pueden ser evitadas.

Cuando las aplicaciones tienen que lidiar con bases de datos existentes siempre preocupaciones de alta seguridad, si un invasor tiene la posibilidad de secuestrar la capa de base de datos de su aplicación, puede elegir entre varias opciones. Robar los datos de los usuarios almacenados para inundarlos de spam no es el peor escenario que podría darse. Aún más problemático sería que se abusara de la información de pago almacenada. Otra posibilidad de un ciberataque SQL Injection es conseguir acceso ilegal a contenidos y/o servicios de pago restringidos. Como podemos ver, hay muchas razones por las que preocuparse por la seguridad de las Aplicaciones (Web).

Para encontrar medidas preventivas eficaces contra las inyecciones SQL, primero debemos comprender cómo funciona un ataque de inyección SQL y a qué puntos debemos prestar atención. En resumen: cada interacción de usuario que procesa la entrada sin filtrar en una consulta SQL es un posible objetivo para un ataque. La entrada de datos puede ser manipulada de manera que la consulta SQL enviada contenga una lógica diferente a la original. El listado 1 le dará una buena idea de lo que podría ser posible.

SELECT Username, Password, Role FROM User
   WHERE Username = 'John Doe' AND Password = 'S3cr3t';
SELECT Username, Password, Role FROM Users
   WHERE Username = 'John Doe'; --' AND Password='S3cr3t';
SELECT Username, Password, Role FROM User
   WHERE Username = 'John Doe' AND Password = 'S3cr3t';
SELECT Username, Password, Role FROM Users
   WHERE Username = 'John Doe'; --' AND Password='S3cr3t';
SQL

SQL

Listing 1: Simple SQL Injection

La primera sentencia del Listado 1 muestra la consulta original. Si no se filtra la entrada para las variables Username y Password, tenemos una falta de seguridad. La segunda consulta inyecta para la variable Username un String con el nombre de usuario John Doe y se extiende con los caracteres ‘; -. Esta sentencia se salta la rama AND y da, en este caso, acceso al login. La secuencia ‘; cierra la sentencia WHERE y con – todos los caracteres siguientes quedan sin comentar. Teóricamente, es posible ejecutar entre ambas secuencias de caracteres cualquier código SQL válido.

Por supuesto, mi plan no es difundir las ideas de que los comandos SQL podrían suscitar las peores consecuencias para la víctima. Con este simple ejemplo, asumo que el mensaje es claro. Necesitamos proteger cada variable de entrada UI en nuestra aplicación contra la manipulación del usuario. Incluso si no se utilizan directamente para consultas a la base de datos. Para detectar esas variables, siempre es una buena idea validar todos los formularios de entrada existentes. Pero las aplicaciones modernas suelen tener más que unos pocos formularios de entrada. Por esta razón, también menciono mantener un ojo en sus puntos finales REST. A menudo sus parámetros también están conectados con consultas SQL.

Por esta razón, la validación de entradas, en general, debería formar parte del concepto de seguridad. Las anotaciones de la especificación Bean Validation [2] son, para este propósito, muy potentes. Por ejemplo, @NotNull, como Anotación para el campo de datos en el objeto de dominio, asegura que el objeto sólo es capaz de persistir si la variable no está vacía. Para utilizar las Anotaciones de Validación de Bean en tu proyecto Java, sólo necesitas incluir una pequeña librería.

<dependency>
    <groupId>org.hibernate.validator</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>${version}</version>
</dependency>

XML

Listing 2: Maven Dependency para Bean Validation

Quizá sea necesario validar estructuras de datos más complejas. Con las expresiones regulares, tiene otra poderosa herramienta en sus manos. Pero tenga cuidado. No es tan fácil escribir una RegEx que funcione correctamente. Veamos un pequeño ejemplo.

public static final String RGB_COLOR = "#[0-9a-fA-F]{3,3}([0-9a-fA-F]{3,3})?";

public boolean validate(String content, String regEx) {
    boolean test;
    if (content.matches(regEx)) {
        test = true;
    } else {
        test = false;
    }
    return test;
}

validate('#000', RGB_COLOR);

Java

Listing 3: Validación mediante expresiones regulares en Java

El RegEx para detectar el esquema de color RGB correcto es bastante simple. Las entradas válidas son #ffF o #000000. El rango para los caracteres es 0-9, y las letras A a F. Insensible a mayúsculas y minúsculas. Cuando desarrollas tu propio RegEx, siempre necesitas comprobar muy bien los límites existentes. Un buen ejemplo es también el formato de 24 horas. Errores típicos son entradas inválidas como 23:60 o 24:00. El método validate compara la cadena de entrada con el RegEx. Si el patrón coincide con la entrada, el método devolverá true. Si quieres obtener más ideas sobre validadores en Java, también puedes consultar mi repositorio de GitHub [3].

En resumen, nuestra primera idea para asegurar la entrada del usuario contra el abuso es filtrar todas las secuencias de caracteres problemáticas, como – y así sucesivamente. Bueno, esta intención de crear una lista de bloqueo no es tan mala. Pero sigue teniendo algunas limitaciones. Al principio, la complejidad de la aplicación aumentó porque bloquear caracteres individuales como -; y ‘ podría causar a veces efectos secundarios no deseados. Además, una limitación de caracteres por defecto en toda la aplicación puede causar problemas. Imagina que hay un área de texto para un sistema de Blog o algo similar.

Esto significa que necesitamos otro concepto potente para filtrar la entrada de forma que nuestra consulta SQL no pueda manipularla. Para alcanzar este objetivo, el estándar SQL tiene una gran solución que podemos utilizar. Los Parámetros SQL son variables dentro de una consulta SQL que serán interpretadas como contenido y no como una sentencia. Esto permite que los textos grandes bloqueen algunos caracteres peligrosos. Echemos un vistazo a cómo funcionará esto en una base de datos PostgreSQL [4].

DECLARE user String;
SELECT * FROM login WHERE name = user;

SQL

Listing 4: Definición de parámetros en PostgreSQL

En el caso de que esté utilizando el mapeador OR Hibernate, existe una forma más elegante con la Java Persistence API (JPA).

String myUserInput;

@PersistenceContext
public EntityManager mainEntityManagerFactory;

CriteriaBuilder builder =
    mainEntityManagerFactory.getCriteriaBuilder();

CriteriaQuery<DomainObject> query =
    builder.createQuery(DomainObject.class);

// create Criteria
Root<ConfigurationDO> root =
    query.from(DomainObject.class);

//Criteria SQL Parameters
ParameterExpression<String> paramKey =
    builder.parameter(String.class);

query.where(builder.equal(root.get("name"), paramKey);

// wire queries together with parameters
TypedQuery<ConfigurationDO> result =
    mainEntityManagerFactory.createQuery(query);

result.setParameter(paramKey, myUserInput);
DomainObject entry = result.getSingleResult();

Java

Listing 5: Uso de parámetros SQL de Hibernate JPA

El listado 5 se muestra como un ejemplo completo de Hibernate utilizando JPA con la API de criterios. La variable para la entrada del usuario se declara en la primera línea. Los comentarios en el listado explican cómo funciona. Como puedes ver, no es ninguna ciencia espacial. La solución tiene otras ventajas además de mejorar la seguridad de la aplicación web. Al principio, no se utiliza SQL plano. Esto asegura que cada sistema de gestión de bases de datos soportado por Hibernate puede ser asegurado por este código.

Puede que el uso parezca un poco más complejo que una simple consulta, pero el beneficio para tu aplicación es enorme. Por otro lado, por supuesto, hay algunas líneas extra de código. Pero no son tan difíciles de entender.

Recursos

Links are only visible for logged in users.

Date vs. Boolean

El modelado de tablas de bases de datos puede dar lugar rápidamente a redundancias que...

Lo último no siempre es lo mejor

traducido por I. A.

Desde hace más de una década, está ampliamente aceptado que los sistemas informáticos deben mantenerse actualizados. Quienes instalan actualizaciones con regularidad reducen el riesgo de tener brechas de seguridad en su ordenador de las que se podría hacer un mal uso. Siempre con la esperanza de que los fabricantes de software corrijan siempre en sus actualizaciones también los fallos de seguridad. Microsoft, por ejemplo, ha impuesto una obligación de actualización a sus usuarios desde la introducción de Windows 10. En el fondo, la idea tenía fundamento. Porque los sistemas operativos sin parches facilitan el acceso a los hackers. Así que el pensamiento: “Lo último es lo mejor” prevaleció hace mucho tiempo.

Los usuarios de Windows tenían poco margen de maniobra. Pero incluso en dispositivos móviles como smartphones y tabletas, las actualizaciones automáticas están activadas en los ajustes de fábrica. Si alojas un proyecto de código abierto en GitHub, recibirás regularmente correos electrónicos sobre las nuevas versiones de las bibliotecas utilizadas. Así que, a primera vista, esto es algo bueno. Sin embargo, si profundizas un poco más en el tema, llegarás rápidamente a la conclusión de que lo último no siempre es lo mejor.

El ejemplo más conocido es Windows 10 y los ciclos de actualización impuestos por Microsoft. Es indiscutible que los sistemas deben comprobarse periódicamente para detectar problemas de seguridad e instalar las actualizaciones disponibles. También es comprensible que el mantenimiento de los sistemas informáticos lleve su tiempo. Sin embargo, resulta problemático cuando las actualizaciones instaladas por el fabricante paralizan todo el sistema y se hace necesaria una nueva instalación porque la actualización no ha sido suficientemente probada. Pero también en el contexto de las actualizaciones de seguridad sin pedir cambios de función al usuario para traer en considero irrazonable. Especialmente con Windows, hay un montón de programas adicionales instalados, que pueden convertirse rápidamente en un riesgo para la seguridad debido a la falta de un mayor desarrollo. Eso significa con todas las consecuencias forzadas actualizaciones de Windows no hacen un equipo seguro, ya que aquí el software instalado adicionalmente no se examina en busca de puntos débiles.

Si echamos un vistazo a los sistemas Android, la situación es mucho mejor. Sin embargo, aquí también hay bastantes puntos criticables. Las aplicaciones se actualizan con regularidad, por lo que la seguridad mejora notablemente. Pero también con Android, cada actualización suele implicar cambios funcionales. Un ejemplo sencillo es el muy popular servicio Google StreetMaps. Con cada actualización, el uso del mapa se vuelve más confuso para mí, ya que se muestra mucha información adicional no deseada, lo que reduce considerablemente la ya limitada pantalla.

Como usuario, afortunadamente todavía no me ha ocurrido que las actualizaciones de aplicaciones en Android hayan paralizado todo el teléfono. Lo que también demuestra que es bastante posible probar exhaustivamente las actualizaciones antes de lanzarlas a los usuarios. Sin embargo, esto no significa que todas las actualizaciones estén exentas de problemas. Los problemas que se pueden observar aquí con regularidad son cosas como un aumento excesivo del consumo de batería.

Las actualizaciones puras del sistema Android, por otro lado, hacen que regularmente el hardware se vuelva tan lento después de casi dos años que a menudo se decide comprar un nuevo smartphone. Aunque el teléfono antiguo todavía esté en buenas condiciones y se pueda utilizar mucho más tiempo. He observado que muchos usuarios experimentados desactivan las actualizaciones de Android al cabo de un año aproximadamente, antes de que el fabricante envíe el teléfono a la obsolescencia.

¿Cómo consigue un silenciador de actualizaciones mantener sus sistemas al día y seguros? Mi planteamiento como desarrollador y gestor de configuración es bastante sencillo. Distingo entre actualización de características y parche de seguridad. Si sigues el versionado semántico en el proceso de publicación y utilizas un modelo de rama por publicación para sistemas SCM como Git, esa distinción puede aplicarse fácilmente.

Pero también me he dedicado a la cuestión de una configuración versionable para aplicaciones de software. Para ello, existe una implementación de referencia en el proyecto TP-CORE en GitHub, que se describe en detalle en el artículo en dos partes Treasue Chest. Después de todo, debemos tener claro que si restablecemos toda la configuración realizada por el usuario a los valores de fábrica durante una actualización, como ocurre con bastante frecuencia con Windows 10, pueden surgir vulnerabilidades de seguridad bastante singulares.

Esto también nos lleva al punto de la programación y cómo GitHub motiva a los desarrolladores a través de correos electrónicos para que incluyan nuevas versiones de las librerías utilizadas en sus aplicaciones. Porque si dicha actualización supone un cambio importante en la API, el problema es el elevado esfuerzo de migración para los desarrolladores. Aquí es donde me ha funcionado una estrategia también bastante sencilla. En lugar de dejarme impresionar por las notificaciones sobre actualizaciones de GitHub, compruebo regularmente a través de OWASP si mis bibliotecas contienen riesgos conocidos. Porque si OWASP detecta un problema, no importa lo costosa que pueda ser una actualización. La actualización y la migración asociada deben aplicarse con prontitud. Esto también se aplica a todas las versiones que todavía están en producción.

Para evitar el infierno de las actualizaciones desde el principio, sin embargo, hay una regla de oro: sólo instalar o utilizar lo que realmente se necesita. Cuantos menos programas se instalen en Windows y menos aplicaciones haya en el smartphone, menos riesgos de seguridad habrá. Esto también se aplica a las bibliotecas de programas. Menos es más desde el punto de vista de la seguridad. Aparte de eso, al prescindir de programas innecesarios, también obtenemos una medida de rendimiento gratuita.

Ciertamente, para muchos usuarios privados la cuestión de las actualizaciones del sistema apenas es relevante. Sólo las nuevas funciones no deseadas en los programas existentes, la degradación del rendimiento o, de vez en cuando, el bloqueo de los sistemas operativos causan un disgusto más o menos fuerte. En el entorno comercial, pueden surgir con bastante rapidez costes considerables, que también pueden repercutir negativamente en los proyectos que se ejecutan. Las empresas y las personas que desarrollan software pueden mejorar considerablemente la satisfacción de los usuarios si distinguen en sus versiones entre parches de seguridad y actualizaciones de características. Y una actualización de características debería contener también todas las actualizaciones de seguridad conocidas.

La Ley de Conway

Dado que el diseño elegido en primer lugar casi nunca es el mejor posible, el…

Lo último no siempre es lo mejor

A qué hay que prestar atención en el entorno comercial para que las actualizaciones de…

README – cómo saber

Los archivos README son archivos de texto y están formateados en notación markdown. El portal…

Opciones de automatización en la gestión de la configuración del software

El desarrollo de software ofrece algunas formas extremadamente eficaces de simplificar tareas recurrentes mediante la…

Anti-Pattern de números de versión

En este artículo analizamos algunas de las mejores prácticas para trabajar con números de versión…