First commit!
This commit is contained in:
commit
573d2da85e
5 changed files with 175 additions and 0 deletions
55
README.md
Normal file
55
README.md
Normal file
|
@ -0,0 +1,55 @@
|
|||
# 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: **SH**ell **N**amespace
|
||||
- .shc: **SH**ell **C**lass
|
||||
|
||||
## Example syntax:
|
||||
|
||||
### Declaring objects.
|
||||
|
||||
`script.sh`:
|
||||
This is the main script which will use our objects.
|
||||
|
||||
```bash
|
||||
. $OOP_ROOT/oop.sh # Import library.
|
||||
|
||||
importNamespace Example.shn
|
||||
|
||||
Example.Object t "Test"
|
||||
```
|
||||
|
||||
`Example.shn`:
|
||||
This file declares our namespace and all the objects within it.
|
||||
|
||||
```bash
|
||||
# Namespace declaration.
|
||||
namespace Example
|
||||
# If namespace is set to null (no argument), then the object will be declared globally.
|
||||
# Otherwise, the object will be declared within the namespace.
|
||||
|
||||
# Object declaration, from class name to file name.
|
||||
class Object "Object.shc"
|
||||
|
||||
```
|
||||
|
||||
`Object.shc`:
|
||||
This file will contain the object code.
|
||||
|
||||
```bash
|
||||
# Property declaration
|
||||
property Object.name
|
||||
|
||||
# Optional constructor.
|
||||
Object.constructor() {
|
||||
Object.name = $1
|
||||
}
|
||||
|
||||
# Example function
|
||||
Object.print() {
|
||||
echo "Example OOP from $($this.name)!"
|
||||
}
|
||||
```
|
7
example/Example.shn
Normal file
7
example/Example.shn
Normal file
|
@ -0,0 +1,7 @@
|
|||
# Namespace declaration.
|
||||
namespace Example
|
||||
# If namespace is set to null (no argument), then the object will be declared globally.
|
||||
# Otherwise, the object will be declared within the namespace.
|
||||
|
||||
# Object declaration, from class name to file name.
|
||||
class Object "Object.shc"
|
12
example/Object.shc
Normal file
12
example/Object.shc
Normal file
|
@ -0,0 +1,12 @@
|
|||
# Property declaration
|
||||
property Object.name
|
||||
|
||||
# Optional constructor.
|
||||
Object.constructor() {
|
||||
Object.name = $1
|
||||
}
|
||||
|
||||
# Example function
|
||||
Object.print() {
|
||||
echo "Example OOP from $(this.name)!"
|
||||
}
|
16
example/script.sh
Normal file
16
example/script.sh
Normal file
|
@ -0,0 +1,16 @@
|
|||
#!/bin/bash
|
||||
OOP_ROOT=..
|
||||
|
||||
. $OOP_ROOT/oop.sh # Import library.
|
||||
|
||||
importNamespace Example.shn
|
||||
|
||||
Example.Object t1 "Test"
|
||||
Example.Object t2 "Example"
|
||||
|
||||
t1.print
|
||||
t2.print
|
||||
|
||||
t1.name = "New name"
|
||||
|
||||
t1.print
|
85
oop.sh
Normal file
85
oop.sh
Normal file
|
@ -0,0 +1,85 @@
|
|||
#!/bin/bash
|
||||
|
||||
# This file contains all functions required to create a namespace.
|
||||
# Internal variables are marked with a beginning underscore, like in most other languages.
|
||||
# Signatures are a list of arguments.. Those within <> are mandatory, the ones within [] are optional.
|
||||
_namespace=""
|
||||
_namespacePath=""
|
||||
|
||||
# Namespace declaration.
|
||||
# Signature: ([string namespaceName])
|
||||
namespace() {
|
||||
_namespace=$1;
|
||||
}
|
||||
|
||||
# Imports a namespace into the current shell.
|
||||
# Signature: (<string namespaceFile>)
|
||||
importNamespace() {
|
||||
namespaceFile=$1
|
||||
# Save the path in order to get the absolute path of the file.
|
||||
_namespacePath=$(realpath $(dirname $namespaceFile))
|
||||
. $namespaceFile
|
||||
}
|
||||
|
||||
# Creates an object instance.
|
||||
# Signature: (<string type>, <string associatedFile>, <string variableName>, [string[] constructorArguments])
|
||||
_createObject() {
|
||||
type=$1
|
||||
associatedFile=$2
|
||||
varName=$3
|
||||
constructorArguments=${@:4}
|
||||
|
||||
# Declare dummy constructor.
|
||||
eval "$varName.constructor() { :; }"
|
||||
# Create property array.
|
||||
eval "declare -Ag _${varName}_properties"
|
||||
# Imports the file and replace all "<Type>." with the variable name.
|
||||
. <(sed s/this\\./$varName./g <(sed s/$type\\./$varName./g $associatedFile))
|
||||
# Call the constructor
|
||||
eval "$varName.constructor $constructorArguments"
|
||||
}
|
||||
|
||||
# Object creation.
|
||||
# Signature: (<string type>, <string associatedFile>)
|
||||
class() {
|
||||
type=$1 # Type of the object as declared within the file.
|
||||
associatedFile=$2
|
||||
objFullName=$type # Type of the object referenced elsewhere
|
||||
|
||||
if [ "$_namespace" != "" ]; then
|
||||
objFullName="${_namespace}.$type"
|
||||
fi
|
||||
|
||||
if [ ${associatedFile::1} != "/" ]; then # Relative path, we save only the absolute path
|
||||
associatedFile="$_namespacePath/$associatedFile"
|
||||
fi
|
||||
# Declares a new function for object initialisation.
|
||||
eval "$objFullName() { _createObject $type $associatedFile \$@; }"
|
||||
}
|
||||
|
||||
# Associated function for properties
|
||||
# Signature: (<string variableName>, <string propertyName>, [string operator, string value])
|
||||
_accessProperty() {
|
||||
varName=$1
|
||||
prop=$2
|
||||
if [ "$3" == "=" ]; then
|
||||
eval "_${varName}_properties[$prop]='${@:4}'"
|
||||
else
|
||||
eval "echo \${_${varName}_properties[$prop]}"
|
||||
fi
|
||||
}
|
||||
|
||||
# Declares a property.
|
||||
# Signature: (<string propertyFullName>)
|
||||
property() {
|
||||
propertyFullName=$1
|
||||
# Split the name by ".". First element is variable name,
|
||||
# second is property name.
|
||||
propertyNames=($(echo $propertyFullName | tr "." "\n"))
|
||||
varName=${propertyNames[0]}
|
||||
prop=${propertyNames[1]}
|
||||
# Default value
|
||||
eval "_${varName}_properties[$prop]=''"
|
||||
# Property alias
|
||||
eval "$propertyFullName() { _accessProperty $varName $prop \$@; }"
|
||||
}
|
Loading…
Reference in a new issue