The Big Reveal
2014-09-08
So it's pretty obvious from my last post that I'm working on a pesudo class module for bashlib.
Currently it's going really well, I wont ever be able to get the full range of class abilities in Bash, what I have can be used in a rudementary way. My previous example wasn't amazing, so here's a better one:
#!/bin/bash source ~/bin/bashlib/bashlib.sh bashlib.load "class" User__construct () { this : name="No_Name" this : dob="1970-01-01" this : phone="11111111111" this : notes="N/A" } User_GetInfo () { echo "User --" $( this . ) echo "Name: " $( this - name ) echo "DOB: " $( this - dob ) echo "Phone: " $( this - phone ) echo "Notes: " $( this - notes ) } USERS=( "bob" "jim" "sarah" "jane" "joe" "noname" ) NAMES=( "Wight, Bob" "Bishop, Jim" "Amis, Sarah" "Smith, Jane" "Blogs, Joe" ) DATES=( "1972-11-18" "1975-08-23" "1979-02-05" "1968-04-22" ) PHONE=( "01189434321" "01189693219" "01189679234" ) for (( i=0; i < ${#USERS[@]}; i++ )); do class.new User "${USERS[${i}]}" { name="${NAMES[${i}]}" dob="${DATES[${i}]}" phone="${PHONE[${i}]}" } done
This takes the information from NAMES/DATES/PHONE arrays and puts them in to classes based on the USERS array. So, you could easily do:
bob : GetInfo jim : GetInfo sarah : GetInfo jane : GetInfo joe : GetInfo noname : GetInfo
Which would then print out the details provided by the previous arrays. The good thing about this class function, is that the CLASS__construct function runs initially. Which means that you can set default variables, instead of relying on the class.new function filling them all in. This is apparent with the users "jane" "joe" and "noname", which have an increasing amount of data ommited from their arrays. Rather than just being blank though, they will take the defaults set in User__construct. With a simple tweak to the for loop above, we can print the information out:
for (( i=0; i < ${#USERS[@]}; i++ )); do class.new User "${USERS[${i}]}" { name="${NAMES[${i}]}" dob="${DATES[${i}]}" phone="${PHONE[${i}]}" } ${USERS[${i}]} : GetInfo (( i != ${#USERS[@]} - 1 )) && echo "==========" done
This will give the results:
% bash class.test.sh User -- bob Name: Wight, Bob DOB: 1972-11-18 Phone: 01189434321 Notes: N/A ========== User -- jim Name: Bishop, Jim DOB: 1975-08-23 Phone: 01189693219 Notes: N/A ========== User -- sarah Name: Amis, Sarah DOB: 1979-02-05 Phone: 01189679234 Notes: N/A ========== User -- jane Name: Smith, Jane DOB: 1968-04-22 Phone: 11111111111 Notes: N/A ========== User -- joe Name: Blogs, Joe DOB: 1970-01-01 Phone: 11111111111 Notes: N/A ========== User -- noname Name: No_Name DOB: 1970-01-01 Phone: 11111111111 Notes: N/A
As I progress with the implimentation, I'll do my best to explain in more detail. But hopefully that gives you some idea of what to expect.
One of the key features of this new class system is the contextual "this" function. It's incredibly difficult to actually return the true name of a function in bash. The FUNCNAME array *might* contain it, if it's called in the right way. But a more surefire way is to simply pass the custom FUNC_NAME variable around (without the user needing to). This allows for a pretty powerful set of commands that you can run by calling "this" instead of needing to use specific names.
In the above example we use 3 of the 4 currently avaliable commands:
this . # . Displays the name of the current class this : variable=value # : Sets variables this - variable # : Prints a variable value this @ FunctionName # @ runs a self named function (eg MyClass_FunctionName)
This allows you to set variables, run other functions all from within a class function and without needing outside help to determine which class it should affect.
The above would be similar to itterating over this (still in a class setting):
sName="joe" echo ${sName} # . Equivilant ${sName} : variable=value # : Equivilant ${sName} : variable # - Equivilant this @ FunctionName # @ runs a self named function (eg MyClass_FunctionName)
While for a single set, that works fine; if you need two users, Joe and Jane, you would need to type a second set of calls. And then for three, four, five etc.
On a similar note, 1.5.3 should be avaliable now and 1.6.0 should be coming in the next few days (I'm still trying to make sure bugs have been ironed out with the class system).
Update: change log for 1.5.3:
1.5.2b -> 1.5.3 +Moved modules from lib/ to modules/ +Added README +Added CHANGELOG +Added offical and extension module notation +Changed how bashlib.version works (it now calls itself with the -v switch)