Programación orientada a Objetos utilizando Bash

    Bash es una shell de *nix muy común, y su lenguaje de programación es puramente procedural y enfocado a la ejecución de comandos. La Programación orientada a Objetos (POO) es un paradigma de programación el cual representa los elementos de un problema como entidades con un conjunto de propiedades y acciones que puede ejecutar.

    Bash es una shell de *nix muy común, y su lenguaje de programación es puramente procedural y enfocado a la ejecución de comandos. La Programación orientada a Objetos (POO) es un paradigma de programación el cual representa los elementos de un problema como entidades con un conjunto de propiedades y acciones que puede ejecutar. Si usas Bash para escribir scripts cortos y simples, con la programación procedural estas bastante bien, no necesitas más. Pero si tu programa se vuelve más y mas grande, un programa monstruoso (> 1000 lineas), entonces necesitas una mejor forma de estructurar tu programa para hacerlo más fácil de mantener y leer. Por supuesto, Bash no ofrece ninguna característica de POO, pero se pude simular usando algunos trucos y agregando solo unas pocas lineas, y te voy a mostrar como.

    Concepto de Programación orientada a Objetos

    Concepto de Programación orientada a Objetos


    ATENCIÓN: Necesitas tener conceptos sólidos de POO y Bash antes de leer esto, no voy a explicar nada de ello aquí.

    Primero que nada, crea un script en el cual definirás tu clase, y dale permisos de ejecución.

    1
    2
    touch vector.sh
    chmod +x vector.sh

    Entonces copia el siguiente código en tu script:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    #!/bin/bash

    # Clase base. (1)
    function Vector()
    {
        # Un puntero a esta clase. (2)
        base=$FUNCNAME
        this=$1

        # Herencia de clases (opcional). (3)
        export ${this}_inherits="Class1 Class2 Class3" # (3.1)

        for class in $(eval "echo \$${this}_inherits")
        do
            for property in $(compgen -A variable ${class}_)
            do
                export ${property/#$class\_/$this\_}="${property}" # (3.2)
            done

            for method in $(compgen -A function ${class}_)
            do
                export ${method/#$class\_/$this\_}="${method} ${this}"
            done
        done

        # Declaramos las propiedades. (4)
        export ${this}_x=$2
        export ${this}_y=$3
        export ${this}_z=$4

        # Declaramos los métodos. (5)
        for method in $(compgen -A function)
        do
            export ${method/#$base\_/$this\_}="${method} ${this}"
        done
    }

    # Representación visual del vector. (6)
    function Vector_show()
    {
        # (7)
        base=$(expr "$FUNCNAME" : '\([a-zA-Z][a-zA-Z0-9]*\)')
        this=$1

        x=$(eval "echo \$${this}_x")
        y=$(eval "echo \$${this}_y")
        z=$(eval "echo \$${this}_z")

        echo "$this ($x, $y, $z)"
    }

    # Suma de vectores.
    function Vector_add()
    {
        base=$(expr "$FUNCNAME" : '\([a-zA-Z][a-zA-Z0-9]*\)')
        this=$1
        other=$2

        # Obtenemos sus componentes
        x1=$(eval "echo \$${this}_x")
        y1=$(eval "echo \$${this}_y")
        z1=$(eval "echo \$${this}_z")

        x2=$(eval "echo \$${other}_x")
        y2=$(eval "echo \$${other}_y")
        z2=$(eval "echo \$${other}_z")

        # Sumamos sus componentes
        x=$(($x1 + $x2))
        y=$(($y1 + $y2))
        z=$(($z1 + $z2))

        # Creamos un nuevo vector. (8)
        Vector 'vector3' $x $y $z

        $vector3_show
    }

    Explicación

    1. Esta función es un equivalente del constructor de una clase. Debe tener el mismo nombre que la clase. El nombre de la clase no puede contener guiones bajos (_). Vamos a usar esta función para crear instancias de la clase “Vector”.
    2. Aquí obtenemos una referencia de la clase base del objeto y una referencia del objeto creado. El primer argumento del constructor debe ser siempre el nombre del objeto a crear.
    3. Este bloque de código simula la herencia múltiple, es opcional y lo puedes remover si no lo necesitas.
      1. Cada método y propiedad de la clase se puede acceder como${this}_nombreDel_metodoPropiedad, o también puedes llamar a la clase base como${base}_nombreDel_metodoPropiedad.
        La herencia múltiple funciona sobrescribiendo los métodos y propiedades (myp) de las clases precedentes como se explica a continuación:
        Class1 < Class2 < Class3 < Base
        • http://www.espaciolinux.com/wp-content/themes/espaciolinux/images/vineta-3.gif); border: none; text-align: left; background-position: 0px 0.5em;">Class2 sobrescribe los myp de Class1.
        • http://www.espaciolinux.com/wp-content/themes/espaciolinux/images/vineta-3.gif); border: none; text-align: left; background-position: 0px 0.5em;">Class3 sobrescribe los myp de Class1 y Class2.
        • http://www.espaciolinux.com/wp-content/themes/espaciolinux/images/vineta-3.gif); border: none; text-align: left; background-position: 0px 0.5em;">Base sobrescribe los myp de Class1Class2 y Class3.
      2. Esto exportará los myp de la clase base como myp del objeto. Leer más abajo.
    4. Cada método y propiedad de la clase se exporta como variable global en la formnombreDelObjeto_nombreDel_metodoPropiedad. Puedes inicializar las propiedades a través de los parámetros del constructor, o mediante un valor predefinido, o dejarlo sin inicializar.
    5. Esto buscará cada función con el patrón ClaseBase_* y lo exportará como variable global reemplazando ClaseBase con el nombre del objeto, el valor de la variable será una cadena con el método de la clase base y el nombre del objeto como primer parámetro que sirve de referencia al mismo.
    6. Los métodos de la clase se definen como ClaseBase_nombreDelmetodo. Los nombres de los métodos pueden contener guiones bajos, pero se recomienda usar camelCase.
    7. Obtiene una referencia a la clase base (no es obligatorio) y el objeto, recuerden que el primer argumento es el nombre del objeto.
    8. Por supuesto, Puedes crear nuevos objetos dentro de los métodos de la misma clase.

    Estamos listos para usar nuestra clase. Creamos un script desde el cual usaremos nuestra clase, dale permisos de ejecución, y copia el siguiente código a dentro de este:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    #!/bin/bash

    # Importamos el archivo con la definición de la clase.
    . vector.sh

    function main()
    {
        # Crea los objetos vectores. (1)
        Vector 'vector1' 1 2 3
        Vector 'vector2' 7 5 3

        # Muestra sus propiedades. (2)
        echo "vector1 ($vector1_x, $vector1_y, $vector1_z)"
        echo "vector2 ($vector2_x, $vector2_y, $vector2_z)"

        # Llama a sus métodos.
        $vector1_show
        $vector2_show

        $vector1_add vector2
    }

    main

    Explicación

    1. Los objetos se declaran como Clase nombreDelObjeto [arg1 arg2 arg3 ...].
    2. Ahora puedes acceder a sus métodos y propiedades como$nombreDelObjeto_nombreDel_metodoPropiedad [arg1 arg2 arg3 ...].

    El resultado de la ejecución del script es:

    1
    2
    3
    4
    5
    6
    $ ./main.sh
    vector1 (1, 2, 3)
    vector2 (7, 5, 3)
    vector1 (1, 2, 3)
    vector2 (7, 5, 3)
    vector3 (8, 7, 6)

    Noticias Linux y más

    7 Razones por las que Linux Mint es el mejor sustituto de Windows 11

    Linux Mint 2025Windows 11 ha traído consigo requisitos de hardware más exigentes, cambios en la interfaz y una mayor integración con servicios en la nube, lo que ha llevado a muchos usuarios a buscar alternativas más ligeras y eficientes.

    Leer más...

    Las 10 mejores herramientas de código abierto para automatización empresarial

    Automatización de procesos EmpresarialesEn el mundo empresarial moderno, la automatización se ha convertido en una necesidad para mejorar la eficiencia, reducir costos y optimizar procesos. El software de código abierto ofrece soluciones flexibles y asequibles para empresas de todos los tamaños.

    Leer más...

    Cómo migrar de SAP a un ERP de código abierto sin complicaciones

    de sap a erp libresMigrar de SAP a un ERP de código abierto puede parecer un desafío, pero con una planificación adecuada y las herramientas correctas, es posible hacer la transición de manera eficiente y sin interrupciones significativas en las operaciones empresariales.

    Leer más...

    Por qué el espíritu del código abierto significa mucho más que una Licencia

    Open SourceEl código abierto no es solo una cuestión de licencias o acceso al código fuente; es un movimiento basado en la colaboración, la transparencia y la libertad de uso.

    Leer más...

    Please publish modules in offcanvas position.