Skip to content

Initial release

Latest
Compare
Choose a tag to compare
@rbaltrusch rbaltrusch released this 09 Mar 19:29
· 32 commits to master since this release

Welcome to the release notes for objectbatch 1.0.0!

Object oriented batch

Objectbatch is an object-oriented extension of the Windows batchfile language, including classes and instances, methods and attributes, inheritance, encapsulation, polymorphism and object composition.

Simple use of a class instance:

::instantiate new object obj of type MyClass
call new MyClass obj construct

::calling method myMethod of instance obj
call # obj myMethod

::reading obj attribute myAttr
echo !%obj%.myAttr!

::writing obj attribute myAttr
set %obj%.myAttr=1

Simple class definition:

::boilerplate
call class %*
%class%

::this is the constructor, adding one custom attribute attr
:public-construct
    call super %*
    set %self%.attr=0
exit /b

Object-oriented concepts

Basic functionality:

Extended functionality:

Keywords

  1. Class definition
  2. Objects
  3. Pointers
  4. Serialization

Class definition

This section contains the keywords that can be used for basic and extended functionality in class definition files.

class

This script must be called at the top of every class definition, as it forms the class header, which is required for objectbatch functionality to work as intended.

A class header may be specified as follows:

call class %*
%class%

object

This is the base class which every class with no defined superclass inherits from. It contains:

  • a call to get_new_objptr, which is required to instantiate a new object
  • a public method __dict__, which may be [inherited] by child classes.

A class header with no defined super class automatically inherits from object. For example:

set __super__=
call class %*
%class%

super

The super keyword must be used in any method inherited from the parent class. For example, a class with no defined superclass must call super in its constructor in order to call the object constructor, from which it automatically inherits, as below:

call class %*
%class%

:public-construct
	call super %*
exit /b

Note here that the super call must always pass the full argument list:

call super %*

sub

The sub keyword needs to be used to achieve object composition, with which an instance of one class can contain an attribute which contains an instance of another class. For example, the class myClass defines an instance attribute b, which contains an instance of class myClass2, as in the following class constructor for myClass:

::myClass class constructor

:public-construct
    call super %*
    call sub myClass2 b construct
    call %self%.a=1
exit /b 0

If instances of myClass2 have attributes b and c, if we define an instance obj of myClass, it would have the following attribute structure:

obj.a
obj.b.b
obj.b.c

Objects

new

The new keyword must be used to instantiate new objects.

It is important for two reasons to use the new keyword instead of just calling a class constructor right away, namely that:

  1. it clears the self pointer, so that a new pointer can be generated for the new object instance.
  2. it sets the type of the object using the magic attribute __class__.

For example, to instantiate a new object obj of type myClass:

call new myClass obj construct

#.bat

The # keyword is a utility script that can be used to call methods without specifying the class name, as below:

::instead of calling myClass.myMethod for the class instance obj this way...
call myClass obj myMethod

::we can use the # syntax, as below
call # obj myMethod

getattr

The getattr keyword is a utility script that can be used to extract the value of an instance attribute without using delayed expansion, as this is not always practical to do. It writes the value of the attribute into a variable called attr. For example, we can extract attribute myAttr from object obj by using:

call getattr obj myAttr
echo %attr%

The alternative using delayed expansion would have been:

echo !%obj%.myAttr!

clear

The clear keyword can be used to remove an object, including all its attributes and pointer variable, from the environment. For example, to clear an object a of class B:

call new B a construct
call clear a

If we assume that class B defines instance attributes c and d and that the instantiated pointer variable a is equal to $123, then we would delete:

  • the object pointer (a)
  • the object attributes ($123.c and $123.d)

Pointers

The pointer scripts are not required when using objectbatch as intended for its object-oriented capabilities. Nonetheless, as pointers are essentially just normal batch variables (due to batch lacking any type of memory access interface), it can be useful to understand what the objectbatch pointers are, as described in the pointers wiki page.

The pointer scripts are used in the objectbatch code to correctly handle defined classes and are included in this wiki for reference only, such that any existing objectbatch functionality can be understood, modified or extended by interested developers. If you would like to contribute to the objectbatch functionality, please visit the contribution guidelines.

get_guid

Generates a unique, random number based on the current time, which is used to create unique pointer names.

get_new_ptr

Generates a new pointer based on a unique number and stores it under the provided variable name. For example:

call get_new_ptr self
::self is equal to something like $193340304202

getptr

Extracts the value from a variable that is being pointed to at an arbitrary depth. For example:

set self=$123
set $123=$234
set $234=hello
set depth=3
call getptr self rv %depth%
::returns rv, which is equal to hello

get_new_objptr

This is a thin wrapper around get_new_ptr, with the only difference being that a new pointer is in fact only created if the specified pointer is not already a defined variable.

set self=$123
call get_new_objptr self
::self is still equal to $123

::clear self and try again
set self=
call get_new_objptr self
::self is now equal to a new pointer

This functionality is important for inheritance in objectbatch, as without it, every class that is inherited from would have its own attributes pointing to a different pointer, i.e. the attributes would not end up in the same object.

getobjptr

This is a thin wrapper around getptr, with the only difference being that the value of the variable that is being pointed to is only extracted if the return value variable name specified is not already a defined variable.

set ptr=$234
set self=$123
call objptr ptr self 1
::self is still equal to $123

::clear self and try again
set self=
call objptr ptr self 1
::self is now equal to $234

This functionality is important for object composition, as without it, every object contained in another object would provide flat, rather than nested, attribute access, with flat attribute access being undesirable. For example, if we have a class A defining attributes a and b, where b is another class B (which itself defines attributes c and d), nested and flat attribute structures would look as below:

Nested (desirable):

A.a
A.b.c
A.b.d

Flat (undesirable):

A.a
A.b
A.c
A.d

Serialization

This can be used similar to json serialization to save all object contents to a file, or to load them back from a file into the batch environment.

save

::get a new pointer and define two attributes a and b dynamically
call get_new_ptr self
set %self%.a=1
set %self%.b=2

::save object pointed to by self to a file called serialized.txt
call save serialized.txt %self%

load

This is similar to json deserialization, by which an object can be loaded from a file back into the batch environment. For example, we can read the file serialized.txt and load the object stored in it by calling:

call load serialized.txt

An optional second argument "delete" may be specified to delete the specified file after loading its contents, as below:

call load serialized.txt "delete"