No description
Find a file
2022-01-01 16:39:35 +01:00
example Adding license, adding the ability to create namespace property holders. 2021-12-29 13:33:51 +01:00
LICENSE.md Adding license, adding the ability to create namespace property holders. 2021-12-29 13:33:51 +01:00
oop.sh Adding proper signatures. 2022-01-01 16:39:35 +01:00
README.md Fixing bug with multiline string in properties. 2021-12-29 20:08:30 +01:00

BashOOP

This idea was inspired from https://stackoverflow.com/a/40981277 in order to be adapted into making a proper OOP with constructors, properties and namespace system for bash.

Reference:

  • .shn: SHell Namespace
  • .shc: SHell Class

Syntax:

To declare objects, there exists 3 scripts.

  • The main script in which we'll use our object (suggested extension: .sh)
  • The namespace declaration script (suggested extension: .shn)
  • The class declaration script (suggested extension: .shc)

The full example is available in the "example" directory.

Declaring objects.

An object has a type name, properties and functions.
To declare a property, you can use the property function. For example, for an class named Object, you can declare a property name using:

property Object.name

NOTE: Bash doesn't have a typing system, so you cannot set property types. You can also set default values by adding a property after the declaration, e.g:

property Object.name "Example"

Class functions are declared the same way you would in bash, except it uses a prefix with object type. For example:

Object.print() {
    echo "Example OOP from $(this.name)!"
}

As you can see here, you can access properties of the object using the this keyword in a function call.
Similarly, you can set properties using a = and value argument. For example:

this.name = "New name"

Objects can also have constructors which will be called at the creation of the object with arguments provided at the creation.
They are simply a function with the name constructor. They aren't mandatory for any object.

Creating a namespace.

While you can import objects directly in the global namespace, it's recommanded to use a separate namespace file.

When you've created your namespace file, you can specify the name of the namespace using the namespace keyword:

namespace Example

You can then declare object classes using the class directive by specifying it's name and associated script file. For example:

class Object "Object.shc"

All objects created under this class will be accessible with namespace as prefix (here our Object class would be accessible under Example.Object).

Similarly, static classes can be declared using the static_class keyword.

static_class Static "Static.shc"

NOTE: Static classes can't have properties. However, you can declare "namespace properties" using first the createPropertyHolder and then declare properties directly in the namespace file like this:

createPropertyHolder Example

property Example.name

Using objects.

Now that we've created our namespace, we will want to use it and our objects in our script.
First things first, we'll want to import the library oop.sh. Depending on where it's located, you will want to use a global variable indicating it's location.

. $OOP_ROOT/oop.sh # Import library.

After that, we'll want to import our namespace file with all it's classes prefixed in the namespace name.

importNamespace "Example.shn"

After that you can declare the object using the following syntax: <ObjectType> <variableName> [constructor arguments...]. For example:

Example.Object obj1 "Test"

You can then call it's functions.

$obj1.print
obj1.print

NOTE: The $ is not mandatory, but is recommanded for clarity.

... or access and edit it's properties.

name=$(obj1.name)
obj1.name = "New name"

You can store objects in variables as a string. For example, you can have have objects as class arguments, function returs or arrays of objects like this:

Example.Object obj1 "First Object"
Example.Object obj2 "Second Object"
objs=($obj1 $obj2)
${objs[0]}.print
${objs[1]}.print

You can also access the static classes by using their class type directly. For example:

Example.Static.print "Example text"

If you find that using the namespace everytime is a bit cumbersome, you can use the using keyword to alias all classes of a namespace into the global namespace.
Example usage:

using Example

Object usingObj "New"

$usingObj.print

NOTE: When using a namespace which contains static classes, please note that the static class file will be re-imported. NOTE: using is not file contextual. So using a namespace will use it in every bash script.