Classes

From Sputnik Wiki
(Difference between revisions)
Jump to: navigation, search
(Overloading Cast: string)
(Magic Functions)
 
(50 intermediate revisions by one user not shown)
Line 1: Line 1:
 +
NOTE - Everything listed on this page DOES work even tho there are not examples for everything they do indeed work if you wish to try it out.
 +
 +
Rather unconventionally Sputnik requires a ; to end a class statement although not a limitation of the parser but I just thought it looked cool.
 +
 
Regular class :
 
Regular class :
  
Line 12: Line 16:
 
casting overloads
 
casting overloads
 
...
 
...
};
+
}
 
</pre>
 
</pre>
  
Line 28: Line 32:
 
casting overloads
 
casting overloads
 
...
 
...
};
+
}
 
</pre>
 
</pre>
  
Line 44: Line 48:
 
casting overloads
 
casting overloads
 
...
 
...
};
+
}
 
</pre>
 
</pre>
  
Line 60: Line 64:
 
casting overloads
 
casting overloads
 
...
 
...
};
+
}
 
</pre>
 
</pre>
  
Line 72: Line 76:
  
 
==== Static Variables ====
 
==== Static Variables ====
 +
 +
==== Properties ====
 +
 +
A property works like a normal variable however instead of returning or setting a variable it executes code when you try get/set the variable take the example below
 +
 +
<syntaxhighlight lang="sputnik">
 +
Class cat
 +
{
 +
# Define a new property
 +
my $Test
 +
{ # Rquired block for it
 +
get # Define the GET accessor
 +
{ # Its block and code to execute
 +
say "Getting the value";
 +
return $Test;
 +
}
 +
set # Define the SET accessor
 +
{ # Its block and code to execute
 +
say "Setting to $value";
 +
$Test = $value;
 +
}
 +
}
 +
}
 +
 +
$a = new cat();
 +
$a->$Test = 77;
 +
say "Value: " . $a->$Test;
 +
 +
# Prints
 +
# Setting to 77
 +
# Getting the value
 +
# Value: 77
 +
</syntaxhighlight>
 +
 +
Inside the GET or SET block the property name becomes a variable so $Test is a property but inside the GET or SET it is a variable like any other and you can get/set to it of course you can choose to ignore the variable entirely and do anything you want inside the GET/SET.
 +
 +
Of note :
 +
* All properties are public and cannot be private however you could restrict the property to only the GET accessor if you wish.
 +
* You can have only one GET accessor.
 +
* You can have only one SET accessor.
 +
* You may have one of each
 +
* If you somehow create a normal variable with the same name as the property it will override the property.
 +
 +
==== Abstract/Override Properties ====
 +
 +
Works exactly same as property above but this time it will be marked as abstract so any class inheriting our class must implement a property by the same name as this one.
 +
 +
To implement it you must use the override keyword as shown in the example below.
 +
 +
<syntaxhighlight lang="sputnik">
 +
Class cat
 +
{
 +
Abstract my $ID { }
 +
}
 +
 +
Class foo extends cat
 +
{
 +
my $_id;
 +
override my $ID
 +
{
 +
get
 +
{
 +
return ++$_id;
 +
}
 +
}
 +
}
 +
 +
$a = new foo();
 +
say "UniqueID: " . $a->$ID;
 +
say "UniqueID: " . $a->$ID;
 +
say "UniqueID: " . $a->$ID;
 +
say "UniqueID: " . $a->$ID;
 +
say "UniqueID: " . $a->$ID;
 +
# Prints
 +
# UniqueID: 1
 +
# UniqueID: 2
 +
# UniqueID: 3
 +
# UniqueID: 4
 +
</syntaxhighlight>
 +
 +
Of note :
 +
* Since this is an abstract class you do not define a GET or SET accessor or else you will get an error.
  
 
==== Functions ====
 
==== Functions ====
 +
 +
==== Public Functions ====
 +
 +
By default all functions are public and there is no *Public* keyword since they are automatically public.
 +
 +
==== Private Functions ====
 +
 +
By default all functions are public and there is no *Public* keyword since they are automatically public however if you want a function to be private you must insert the "Private" keyword before the function.
 +
 +
Once private is defined you can call the function by name inside the class and by using $this-> but you can't call the function from outside the class this will prevent people from using functions that could cause functions such as internal functions that must only be used by the class itself.
 +
 +
<syntaxhighlight lang="sputnik">
 +
Class Test
 +
{
 +
Function __Construct()
 +
{
 +
say "Made...";
 +
}
 +
Function Testy()
 +
{
 +
say "Testy";
 +
Foo("Called from class");
 +
$this->Foo("Called from class THIS");
 +
}
 +
Private Function Foo($value)
 +
{
 +
say "Foo: $value";
 +
}
 +
}
 +
 +
$a = new Test();
 +
$a->Testy();
 +
$a->Foo("called from pointer"); # Fails cannot access private function
 +
# Prints
 +
# Made...
 +
# Testy
 +
# Foo: Called from class
 +
# Foo: Called from class THIS
 +
 +
# then throws an exception
 +
</syntaxhighlight>
 +
 +
==== Abstract/Override Functions ====
 +
 +
Works exactly same as functions above but this time it will be marked as abstract so any class inheriting our class must implement a function by the same name as this one.
 +
 +
To implement it you must use the override keyword as shown in the example below.
 +
 +
<syntaxhighlight lang="sputnik">
 +
// Define a class we will inherit
 +
Class EngineInfo
 +
{
 +
// define an abstract function
 +
abstract Function Engine() { }
 +
// define two abstract properties
 +
Abstract my $GearVer { }
 +
Abstract my $GearBox { }
 +
}
 +
 +
// Define the final class
 +
Class Car extends EngineInfo
 +
{
 +
// override the abstract function Engine()
 +
override Function Engine()
 +
{
 +
return "V8";
 +
}
 +
// streamlined property
 +
override my $GearVer { get { return "1.0"; } }
 +
// expanded property
 +
override my $GearBox
 +
{
 +
get
 +
{
 +
return "12Gears";
 +
}
 +
}
 +
}
 +
 +
my $c = new Car();
 +
say "Engine: " . $c->Engine();
 +
say "GearVer: " . $c->$GearVer;
 +
say "GearBox: " . $c->$GearBox;
 +
// PRINTS
 +
// Engine: V8
 +
// GearVer: 1.0
 +
// GearBox: 12Gears
 +
</syntaxhighlight>
 +
 +
Of note :
 +
* Since this is an abstract class you do not define any statements in the { } block of the abstract function or else you will get an error.
  
 
==== Static Functions ====
 
==== Static Functions ====
 +
 +
Static functions can't be private.
 +
 +
==== Magic Functions ====
 +
 +
A magic function is basically a function that starts with __ and gets executed when a specific core function is used with the class variable in its context here is an example
 +
 +
<syntaxhighlight lang="sputnik">
 +
Class Test
 +
{
 +
my $data = array(); # A simple array to hold our data
 +
Function __Construct() # Is called when you do new ClassName()
 +
{
 +
say "__Construct() called";
 +
}
 +
Function __Destruct() # Is called when you do unset($class)
 +
{
 +
say "__Destruct() called";
 +
}
 +
Function __Set($key, $value) # Is called when you do $class['key'] =
 +
{
 +
say "__Set() called with key '$key' and value '$value'";
 +
$data[$key] = $value;
 +
return true;
 +
}
 +
Function __Get($key) # Is called when you do $class['key']
 +
{
 +
say "__Get() called with key '$key'";
 +
return $data[$key];
 +
}
 +
Function __Unset($key) # Is called when you do unset($class['key'])
 +
{
 +
say "__Unset() called with key '$key'";
 +
unset($data[$key]);
 +
return true;
 +
}
 +
Function __IsSet($key) # Is called when you do isset($class['key']) or isset($class)
 +
{
 +
# The key will be NULL if this was called using isset($class)
 +
say "__IsSet() called with key '$key'";
 +
return isset($data[$key]);
 +
}
 +
Function __Call() # Is called when you do $class() and try use it as a function
 +
{
 +
say "Hello from _Call"; # we could use params and return a value
 +
}
 +
Function PrintAll() # Just print the current data the class holds
 +
{
 +
printr $data;
 +
}
 +
}
 +
 +
$a = new Test();
 +
$a(); # Treat the class as a function
 +
$a['Foo'] = "Bar"; # Set key 'Foo' to 'Bar'
 +
$a['Cat'] = "Meow"; # Set key 'Cat' to 'Meow'
 +
say "Foo is: " . $a['Foo']; # Get key 'Foo'
 +
say isset($a); # Check if the class itself is set
 +
say isset($a['Foo']); # Check if the key 'Foo' is set
 +
$a->PrintAll(); # Print what the class contains
 +
unset($a['Foo']); # Unset the key 'Foo'
 +
$a->PrintAll(); # Print what the class contains
 +
unset($a); # dispose of the class
 +
printr(vardump($a)); # NULL
 +
</syntaxhighlight>
 +
 +
==== Magic Functions/Properties (others) ====
 +
 +
These magic functions and properties are used by other core functions that are nothing to do with classes directly (usually)but will work classes in a special way if you extend or do something that it requires.
 +
 +
* [[Core Function Count|Count( )]] -- This lets you override what number count() will return when it is used against the class
 +
* [[Core Function JsonEncode|JsonEncode( )]] -- This one lets you control what gets serialized and how
  
 
==== Operator Overloads ====
 
==== Operator Overloads ====
  
 
==== Cast Overloads ====
 
==== Cast Overloads ====
 +
 +
=== Embedding ===
 +
 +
A class can be embedded inside an IF statement (or any statement) so that it can be created on a conditional for example:
 +
 +
<syntaxhighlight lang="sputnik">
 +
// Check if the class already exists and
 +
// if it does already exists don't create it
 +
if (!ClassExists("Cat"))
 +
{
 +
// Create the class using the Embedded keyword
 +
Embedded Class Cat
 +
{
 +
Function __construct()
 +
{
 +
say "testy!";
 +
}
 +
}; // note ; is required here
 +
}
 +
$a = new cat();
 +
// PRINTS
 +
// testy!
 +
</syntaxhighlight>
  
 
=== Remarks ===
 
=== Remarks ===
Line 94: Line 366:
  
 
=== Multiple Inheritance Classes ===
 
=== Multiple Inheritance Classes ===
 +
 +
Sputnik supports multiple inheritance in a rather unique and powerful way.
 +
 +
<syntaxhighlight lang="sputnik">
 +
// Define a class we will inherit
 +
Class EngineInfo
 +
{
 +
// define an abstract function
 +
abstract Function Engine() { }
 +
// define two abstract properties
 +
Abstract my $GearVer { }
 +
Abstract my $GearBox { }
 +
// define a normal Function
 +
// the final class will inherit this
 +
// and since it is not an abstract it will
 +
// appear as if it was literally inside the
 +
// original
 +
Function EngineTest()
 +
{
 +
say "Testing engine...";
 +
}
 +
}
 +
 +
// Define another class we will inherit
 +
Class CarColour
 +
{
 +
// define an abstract property
 +
Abstract my $Colour { }
 +
// define a normal Function
 +
// the final class will inherit this
 +
// and since it is not an abstract it will
 +
// appear as if it was literally inside the
 +
// original
 +
Function ColourTest()
 +
{
 +
say "Testing colours...";
 +
}
 +
}
 +
 +
// Define the final class
 +
// We will multiple inherit both
 +
// EngineInfo AND CarColour
 +
Class Car extends EngineInfo, CarColour
 +
{
 +
// override the abstract function Engine()
 +
override Function Engine()
 +
{
 +
return "V8";
 +
}
 +
// streamlined properties
 +
override my $GearVer { get { return "1.0"; } }
 +
override my $Colour { get { return "Red"; } }
 +
// expanded property
 +
override my $GearBox
 +
{
 +
get
 +
{
 +
return "12Gears";
 +
}
 +
}
 +
}
 +
 +
my $c = new Car();
 +
say "Colour: " . $c->$Colour;
 +
say "Engine: " . $c->Engine();
 +
say "GearVer: " . $c->$GearVer;
 +
say "GearBox: " . $c->$GearBox;
 +
$c->EngineTest();
 +
$c->ColourTest();
 +
// PRINTS
 +
// Colour: Red
 +
// Engine: V8
 +
// GearVer: 1.0
 +
// GearBox: 12Gears
 +
// Testing engine...
 +
// Testing colours...
 +
</syntaxhighlight>
  
 
=== Cast Overloading ===
 
=== Cast Overloading ===
  
Sputnik allows you to overload all the castings such as (int)value etc this is useful if you have a class that uses multiple variables and you would like them all added together each time you use (float)$myclass.
+
Sputnik allows you to overload all the castings such as (int)value etc this is useful if you have a class that uses multiple variables and you would like them all added together each time you use (float)$myclass (or any cast you are doing such as (string) also it will run the cast if the function you are using wants to convert the variable into a string such as print()).
  
Warning - Cast overloading does not apply to the function cast such as int( value ) since that is a function designed to accept an expression and return it converted it is not a cast.
+
==== Overloading Cast: null ====
  
 
==== Overloading Cast: char ====
 
==== Overloading Cast: char ====
Line 106: Line 455:
  
 
==== Overloading Cast: sbyte ====
 
==== Overloading Cast: sbyte ====
 
==== Overloading Cast: ushort ====
 
  
 
==== Overloading Cast: uint16 ====
 
==== Overloading Cast: uint16 ====
 
==== Overloading Cast: uint ====
 
  
 
==== Overloading Cast: uint32 ====
 
==== Overloading Cast: uint32 ====
  
 
==== Overloading Cast: uint64 ====
 
==== Overloading Cast: uint64 ====
 
==== Overloading Cast: ulong ====
 
 
==== Overloading Cast: short ====
 
  
 
==== Overloading Cast: int16 ====
 
==== Overloading Cast: int16 ====
 
==== Overloading Cast: int ====
 
  
 
==== Overloading Cast: int32 ====
 
==== Overloading Cast: int32 ====
  
 
==== Overloading Cast: int64 ====
 
==== Overloading Cast: int64 ====
 +
 +
==== Overloading Cast: intptr ====
 +
 +
==== Overloading Cast: uintptr ====
  
 
==== Overloading Cast: long ====
 
==== Overloading Cast: long ====
Line 151: Line 494:
 
return "Account '$Name' Credits '$Credits'";
 
return "Account '$Name' Credits '$Credits'";
 
}
 
}
};
+
}
 
$nacc = New Account("FoX", 777);
 
$nacc = New Account("FoX", 777);
 
println( (string)$nacc ); // Prints Account 'FoX' Credits '777'
 
println( (string)$nacc ); // Prints Account 'FoX' Credits '777'
 
</syntaxhighlight>
 
</syntaxhighlight>
  
==== Operator Overloading ====
+
==== Overloading Cast: binary ====
 +
 
 +
=== Operator Overloading ===
  
 
Sputnik allows you to overload a vast array of operators on your classes this is very helpful for all kinds of things example imagine you have a class that contains 3 varibles X Y and Z and you want to add another classes variables X Y Z onto yours creating a += operator you could quite simply do just that example:
 
Sputnik allows you to overload a vast array of operators on your classes this is very helpful for all kinds of things example imagine you have a class that contains 3 varibles X Y and Z and you want to add another classes variables X Y Z onto yours creating a += operator you could quite simply do just that example:
Line 182: Line 527:
 
==== Overloading = ====
 
==== Overloading = ====
  
This cannot be overloaded!
+
You can overload the = such as $a = 10;
 +
 
 +
However you must remember once this is overloaded you cant change the variable by simply $a = null;
 +
 
 +
Since it will just use the overloaded function instead of setting the variable.
 +
 
 +
To delete a variable you have given = casting to you must use unset($a); instead.
  
 
==== Overloading += ====
 
==== Overloading += ====
Line 209: Line 560:
  
 
==== Overloading <<= ====
 
==== Overloading <<= ====
 +
 +
==== Overloading >>>= ====
 +
 +
==== Overloading <<<= ====
 +
 +
==== Overloading &&= ====
 +
 +
==== Overloading ||= ====
  
 
==== Overloading | ====
 
==== Overloading | ====
Line 233: Line 592:
  
 
==== Overloading >> ====
 
==== Overloading >> ====
 +
 +
==== Overloading <<< ====
 +
 +
==== Overloading >>> ====
  
 
==== Overloading ++ ====
 
==== Overloading ++ ====
Line 254: Line 617:
 
$this->$z++;
 
$this->$z++;
 
}
 
}
};
+
}
 
$cat1 = new Vec3(10, 20, 30);
 
$cat1 = new Vec3(10, 20, 30);
 
println("BEFORE ++");
 
println("BEFORE ++");
Line 296: Line 659:
 
$this->$z--;
 
$this->$z--;
 
}
 
}
};
+
}
 
$cat1 = new Vec3(10, 20, 30);
 
$cat1 = new Vec3(10, 20, 30);
 
println("BEFORE --");
 
println("BEFORE --");
Line 302: Line 665:
 
println("Class variable Y: " . $cat1->$y);
 
println("Class variable Y: " . $cat1->$y);
 
println("Class variable Z: " . $cat1->$z);
 
println("Class variable Z: " . $cat1->$z);
$cat1++;
+
$cat1--;
 
println("AFTER --");
 
println("AFTER --");
 
println("Class variable X: " . $cat1->$x);
 
println("Class variable X: " . $cat1->$x);
Line 319: Line 682:
  
 
==== Overloading == ====
 
==== Overloading == ====
 +
 +
==== Overloading === ====
  
 
==== Overloading != ====
 
==== Overloading != ====
 +
 +
==== Overloading !== ====
  
 
==== Overloading < ====
 
==== Overloading < ====
Line 339: Line 706:
  
 
==== Overloading neqi ====
 
==== Overloading neqi ====
 +
 +
==== Overloading cmp ====
 +
 +
==== Overloading cmpi ====
 +
 +
==== Overloading lt ====
 +
 +
==== Overloading gt ====
 +
 +
==== Overloading le ====
 +
 +
==== Overloading ge ====
 +
 +
==== Overloading lti ====
 +
 +
==== Overloading gei ====
 +
 +
==== Overloading lei ====
 +
 +
==== Overloading gei ====
 +
 +
==== Overloading lg ====
 +
 +
==== Overloading lgi ====
  
 
==== Overloading || ====
 
==== Overloading || ====
Line 344: Line 735:
 
==== Overloading && ====
 
==== Overloading && ====
  
==== A large example ====
+
==== Overloading [] ====
 
+
This is a Vector3 class created in Sputnik for use it demonstrates internal and static functions as well as vast operator overloading.
+
  
 
<syntaxhighlight lang="sputnik">
 
<syntaxhighlight lang="sputnik">
// Vector3 Class ported to Sputnik by UberFoX
+
Class Testy
//
+
// Function Key:
+
// ! = Returns no return value
+
// * = Returns a new Vector3
+
// % = Returns a numeric value
+
// " = Returns a string
+
// @ = Returns an array
+
// : = Returns numeric where higher than 0 is true
+
//
+
// Function Argument Key:
+
// * = Requires Vector3
+
// % = Requires numeric value
+
//
+
// Static Functions // To be called from anywhere like: vec3::FunctionName()
+
// * CrossProduct(*, *) // Determine the cross product of two Vectors
+
// % DotProduct(*, *) // Determine the dot product of two Vectors
+
// % MixedProduct(*, *, *) // Determine the mixed product of three Vectors
+
// * Normalize(*) // Get the normalized vector of a vector
+
// % Multiply(*, *) //  Returns the dot product: vector1.X * vector2.X + vector1.Y*vector2.Y
+
// % Determinant(*, *) // Returns the determinant det(vector1, vector2)
+
// * SumComponentSqrs(*) // The sum of a Vector3's squared components
+
// * SqrComponents(*) // A Vector3's components squared
+
// % SumComponents(*) // The sum of a Vector3's components
+
// % Distance(*, *) // Find the distance between two Vectors
+
// % Angle(*, *) // Find the angle between two Vectors
+
//  % AngleBetween(*, *) // The angle in degrees between 2 vectors
+
// * Max(*, *) // Compares the magnitude of two Vectors and returns the greater Vector3
+
// * Min(*, *) // Compares the magnitude of two Vectors and returns the lesser Vector3
+
// ! Yaw(*, %) // Rotates a Vector3 around the Y axis
+
// ! Pitch(*, %) // Rotates a Vector3 around the X axis
+
// ! Roll(*, %) // Rotates a Vector3 around the Z axis
+
// % Abs(*) // Find the absolute value of a Vector3
+
// * PowComponents(*, %) // The individual multiplication to a power of a Vector3's components
+
// : IsBackFace(*, *) // Checks if a face normal vector represents back face
+
// : IsUnitVector(*) // Checks if a vector is a unit vector
+
// : IsPerpendicular(*, *) // Checks if two Vectors are perpendicular
+
//  * MinValue() // Retuns the smallest vector possible (based on the double precision floating point structure) for you to use
+
//  * MaxValue() // Retuns the largest vector possible (based on the double precision floating point structure) for you to use
+
//  * Zero() // Retuns an empty Vector3 (0, 0, 0) object for you to use
+
//
+
// Internal Functions // To be called from a new vector3 object like: $Vec1->FunctionName()
+
// @ GetArray() // Return a 3 element array of this Vector3
+
// % Magnitude() // Magnitude (aka. length or absolute value) of the Vector3
+
// % Length() // Magnitude (aka. length or absolute value) of the Vector3
+
// % LengthSquared() // The squared length of this Vector
+
// * CrossProduct(*) // Determine the cross product of this Vector3 and another
+
// % DotProduct(*) // Determine the dot product of this Vector3 and another
+
// % MixedProduct() // Determine the mixed product of this and 2 other Vectors
+
// ! Normalize() // Get the normalized vector
+
// * SumComponentSqrs() // The sum of this Vector3's squared components
+
// * SqrComponents() // The individual square root of this Vector3's components
+
// % SumComponents() // The sum of this Vector3's components
+
// % Distance(*) // Find the distance between this vector and another
+
// " toString() // Return a string of all the vectors variables to print or so
+
// % Angle(*) // Find the angle between this Vector3 and another
+
//  % AngleBetween(*) // The angle in degrees between this and another vector
+
// * Max(*) // Compares the magnitude of this and another and returns the greater Vector3
+
// * Min(*) // Compares the magnitude of this and another and returns the lesser Vector3
+
// ! Yaw(%) // Rotates this Vector3 around the Y axis
+
// ! Pitch(%) // Rotates this Vector3 around the X axis
+
// ! Roll(%) // Rotates this Vector3 around the Z axis
+
// % Abs() // Find the absolute value of this Vector3
+
// * PowComponents(%) // The individual multiplication to a power of this Vector3's components
+
// : IsBackFace(*) // Checks if a face normal vector represents back face
+
// : IsUnitVector() // Checks if this vector is a unit vector
+
// : IsPerpendicular(*) // Checks this and another Vector are perpendicular
+
//
+
// Overloaded Operators // To be called like: $vec1 += $vec2
+
// Supported (If the operator aint on this list then its not supported so dont use it)
+
// +
+
// -
+
// *
+
// /
+
// **
+
// %
+
// +=
+
// -=
+
// *=
+
// /=
+
// **=
+
// %=
+
// ==
+
// !=
+
// <
+
// >
+
// <=
+
// >=
+
// <>
+
Class Vec3
+
 
{
 
{
my $x = 0;
+
my $Values;
my $y = 0;
+
Function __Construct()
my $z = 0;
+
// The constructor can either clone a Vector3 or create a new one example
+
// $v2 = new Vec3( $v1 ) // Will clone a vector $v1 but only if theres only 1 param
+
// If theres more than 1 param it will simply create a new vector using whatever variables it can find or use defaults
+
Function __construct($x = 0, $y = 0, $z = 0)
+
 
{
 
{
If( UBound(@args) == 1 && isVarClass($x, "vec3" ) )
+
$this->$Values = array();
{
+
println("A new Testy() class was made");
$this->$x = $x->$x;
+
$this->$y = $x->$y;
+
$this->$z = $x->$z;
+
}
+
else
+
{
+
$this->$x = (double)$x;
+
$this->$y = (double)$y;
+
$this->$z = (double)$z;
+
}
+
 
}
 
}
// Return a string of all the vectors variables to print or so
+
Function __Deconstruct()
Function toString()
+
 
{
 
{
return "($x, $y, $z)";
+
$this->$Values = array();
 +
println("A Testy() class was destroyed");
 
}
 
}
// Return a 3 element array of this Vector3
+
Function PrintMe()
Function GetArray()
+
 
{
 
{
return array($x, $y, $z);
+
println("Values BELOW");
 +
printr($Values);
 +
println("Values ABOVE");
 
}
 
}
    // Magnitude (aka. length or absolute value) of the Vector3
+
// Overload the [] operator
Function Magnitude()
+
// Note that you don't get the value that is going to
 +
// to the [] this is because Sputnik doesn't yet know
 +
// what is going inside it however it knows the array
 +
// must be extended to allow something to go inside it.
 +
// So we simply extend the array and return a pointer to it
 +
// This will allow the array element to be set later
 +
Operator "[]"
 
{
 
{
return Sqrt ( SumComponentSqrs() );
+
// & means return a pointer to new index
 +
return &$this->$Values[];
 
}
 
}
    // The length of this Vector 
+
    Function Length()
+
}
    {
+
 
return Sqrt($x * $x + $y * $y);
+
my $Testy = new Testy();
    }
+
// Now we use use the new index that was returned and place stuff in it
    // The squared length of this Vector 
+
// However it is being returned as a POINTER so to make use of it we
    Function LengthSquared()
+
// resolve it back into a variable using the * symbol.
    {
+
// * Causes a pointer to become as if it was the actual object.
return ($x * $x + $y * $y);
+
*$Testy[] = "One";
    }
+
*$Testy[] = "Two";
// Find the distance between two Vectors
+
*$Testy[] = "Three";
// Pythagoras theorem on two Vectors
+
$Testy->PrintMe();
    Static Function Distance(Vec3 $v1, Vec3 $v2)
+
Unset($Testy);
 +
</syntaxhighlight>
 +
 
 +
==== Overloading []! ====
 +
 
 +
<syntaxhighlight lang="sputnik">
 +
Class Testy
 +
{
 +
my $Values;
 +
Function __Construct()
 
{
 
{
return Sqrt
+
$this->$Values = array();
(
+
println("A new Testy() class was made");
($v1->$x - $v2->$x) * ($v1->$x - $v2->$x) +
+
($v1->$y - $v2->$y) * ($v1->$y - $v2->$y) +
+
($v1->$z - $v2->$z) * ($v1->$z - $v2->$z)
+
);
+
 
}
 
}
// Find the distance between this vector and another
+
Function __Deconstruct()
    Function Distance(Vec3 $other)
+
 
{
 
{
return self::Distance($this, $other);
+
$this->$Values = array();
 +
println("A Testy() class was destroyed");
 
}
 
}
    // Determine the cross product of two Vectors
+
Function PrintMe()
    // Determine the vector product
+
    // Determine the normal vector (Vector3 90° to the plane)
+
    Static Function CrossProduct(Vec3 $v1, Vec3 $v2)
+
    {
+
        return new Vec3( $v1->$y * $v2->$z - $v1->$z * $v2->$y,
+
$v1->$z * $v2->$x - $v1->$x * $v2->$z,
+
$v1->$x * $v2->$y - $v1->$y * $v2->$x);
+
    }
+
    // Determine the cross product of this Vector3 and another
+
    Function CrossProduct(Vec3 $other)
+
    {
+
        return self::CrossProduct($this, $other);
+
    }
+
    // Determine the dot product of two Vectors
+
    Static Function DotProduct(Vec3 $v1, Vec3 $v2)
+
    {
+
        return ( $v1->$x * $v2->$x + $v1->$y * $v2->$y + $v1->$z * $v2->$z );
+
    }
+
    // Determine the dot product of this Vector3 and another
+
    Function DotProduct(Vec3 $other)
+
    {
+
        return self::DotProduct($this, $other);
+
    }
+
    // Determine the mixed product of three Vectors
+
    Static Function MixedProduct(Vec3 $v1, Vec3 $v2, Vec3 $v3)
+
    {
+
        return DotProduct(CrossProduct($v1, $v2), $v3);
+
    }
+
    // Determine the mixed product of this and 2 other Vectors
+
    Function MixedProduct(Vec3 $other_v1, Vec3 $other_v2)
+
    {
+
        return self::DotProduct(self::CrossProduct($this, $other_v1), $other_v2);
+
    }
+
    // The individual multiplication to a power of a Vector3's components
+
    Static Function PowComponents(Vec3 $v1, $power)
+
    {
+
        return
+
        (
+
            new Vec3
+
                (
+
                    Pow($v1->$X, $power),
+
                    Pow($v1->$Y, $power),
+
                    Pow($v1->$Z, $power)
+
                )
+
        );
+
    }
+
    // The individual multiplication to a power of this Vector3's components
+
    Function PowComponents($power)
+
    {
+
        my $v1 = self::PowComponents($this, $power);
+
$x = $v1->$x;
+
$y = $v1->$y;
+
$z = $v1->$z;
+
unset($v1);
+
    }
+
// Get the normalized vector of a vector
+
// Get the unit vector
+
// Scale a Vector3 so that the magnitude is 1
+
Static Function Normalize(Vec3 $v1)
+
 
{
 
{
// Check for divide by zero errors
+
println("Values BELOW");
if ( $v1->Magnitude() == 0 )
+
printr($Values);
{
+
println("Values ABOVE");
throw("DivideByZeroException @ _Normalize");
+
}
+
else
+
{
+
// find the inverse of the vectors magnitude
+
            $inverse = 1 / $v1->Magnitude();
+
return new Vec3($v1->$x * $inverse, $v1->$y * $inverse, $v1->$z * $inverse);
+
}
+
 
}
 
}
// Get the normalized vector
+
// Overload the [] operator
Function Normalize()
+
// Note that you don't get the value that is going to
 +
// to the [] this is because Sputnik doesn't yet know
 +
// what is going inside it however it knows the array
 +
// must be extended to allow something to go inside it.
 +
// So we simply extend the array and return a pointer to it
 +
// This will allow the array element to be set later
 +
Operator "[]"
 
{
 
{
        my $v1 = self::Normalize($this);
+
// & means return a pointer to new index
$x = $v1->$x;
+
return &$this->$Values[];
$y = $v1->$y;
+
$z = $v1->$z;
+
unset($v1);
+
 
}
 
}
    // Multiply - Returns the dot product: vector1.X*vector2.X + vector1.Y*vector2.Y 
+
// Overload the []! operator
    Static Function Multiply(Vec3 $vector1, Vec3 $vector2)
+
// Same as above nothing special here
    {
+
Operator "[]!"
        return $vector1->$x * $vector2->$x + $vector1->$y * $vector2->$y;
+
    }
+
    // Determinant - Returns the determinant det(vector1, vector2)
+
    Static Function Determinant(Vec3 $vector1, Vec3 $vector2)
+
    {
+
        return $vector1->$x * $vector2->$y - $vector1->$y * $vector2->$x;
+
    }
+
    // The sum of a Vector3's squared components
+
    Static Function SumComponentSqrs(Vec3 $v1)
+
    {
+
        return self::SqrComponents($v1)->SumComponents();
+
    }
+
    // The sum of this Vector3's squared components
+
    Function SumComponentSqrs()
+
    {
+
        return self::SumComponentSqrs($this);
+
    }
+
    // A Vector3's components squared
+
    Static Function SqrComponents(Vec3 $v1)
+
    {
+
        return new Vec3($v1->$x * $v1->$x, $v1->$y * $v1->$y, $v1->$z * $v1->$z);
+
    }
+
    // The individual square root of this Vector3's components
+
    Function SqrComponents()
+
    {
+
        my $v1 = self::SqrComponents($this);
+
$x = $v1->$x;
+
$y = $v1->$y;
+
$z = $v1->$z;
+
unset($v1);
+
    }
+
    // The sum of a Vector3's components
+
    Static Function SumComponents(Vec3 $v1)
+
    {
+
        return ($v1->$x + $v1->$y + $v1->$z);
+
    }
+
    // The sum of this Vector3's components
+
    Function SumComponents()
+
    {
+
        return self::SumComponents($this);
+
    }
+
    // The angle in degrees between 2 vectors
+
    Static Function AngleBetween(Vec3 $vector1, Vec3 $vector2)
+
    {
+
        my $sin = $vector1->$x * $vector2->$y - $vector2->$x * $vector1->$y;
+
        my $cos = $vector1->$x * $vector2->$x + $vector1->$y * $vector2->$y;
+
        return Atan($sin, $cos) * (180 / @PI);
+
    }
+
    // The angle in degrees between this and another vector
+
    Function AngleBetween(Vec3 $vector1)
+
    {
+
        my $sin = $x * $vector1->$y - $vector1->$x * $y;
+
        my $cos = $x * $vector1->$x + $y * $vector1->$y;
+
        return Atan($sin, $cos) * (180 / @PI);
+
    }
+
// Find the angle between two Vectors
+
    Static Function Angle(Vec3 $v1, Vec3 $v2)
+
 
{
 
{
return Acos(self::Normalize($v1)->DotProduct(self::Normalize($v2)));
+
return &$this->$Values[]!;
}
+
}
// Find the angle between this Vector3 and another
+
}
Function Angle(Vec3 $other)
+
my $Testy = new Testy();
 +
// Now we use use the new index that was returned and place stuff in it
 +
// However it is being returned as a POINTER so to make use of it we
 +
// resolve it back into a variable using the * symbol.
 +
// * Causes a pointer to become as if it was the actual object.
 +
*$Testy[] = "One";
 +
*$Testy[] = "Two";
 +
*$Testy[] = "Three";
 +
*$Testy[]! = "Zero";
 +
$Testy->PrintMe();
 +
Unset($Testy);
 +
</syntaxhighlight>
 +
 
 +
==== Overloading [<>] ====
 +
 
 +
<syntaxhighlight lang="sputnik">
 +
Class Testy
 +
{
 +
my $Values;
 +
Function __Construct()
 
{
 
{
return self::Angle($this, $other);
+
$this->$Values = array();
 +
println("A new Testy() class was made");
 
}
 
}
// Rotates a Vector3 around the Y axis
+
Function __Deconstruct()
    Static Function Yaw(Vec3 $v1, $degree)
+
 
{
 
{
return new Vec3
+
$this->$Values = array();
(
+
println("A Testy() class was destroyed");
($v1->$z * Sin($degree)) + ($v1->$x * Cos($degree)),
+
$v1->$y,
+
($v1->$z * Cos($degree)) - ($v1->$x * Sin($degree))
+
);
+
 
}
 
}
// Rotates this Vector3 around the Y axis
+
// Overload the [] operator
Function Yaw($degree)
+
// Note that you dont get the value that is going to
 +
// to the [] this is because Sputnik doesnt yet know
 +
// what is going inside it however it knows the array
 +
// must be extended to allow something to go inside it.
 +
// So we simply extend the array and return a pointer to it
 +
// This will allow the array element to be set later
 +
Operator "[]"
 
{
 
{
        my $v1 = self::Yaw($this, $degree);
+
return &$this->$Values[];
$x = $v1->$x;
+
$y = $v1->$y;
+
$z = $v1->$z;
+
unset($v1);
+
 
}
 
}
// Rotates a Vector3 around the X axis
+
// Overload the []! operator
    Static Function Pitch(Vec3 $v1, $degree)
+
// Same as above nothing special here
 +
Operator "[]!"
 
{
 
{
return new Vec3
+
return &$this->$Values[]!;
(
+
$v1->$x,
+
($v1->$y * Cos($degree)) - ($v1->$z * Sin($degree)),
+
($v1->$y * Sin($degree)) + ($v1->$z * Cos($degree))
+
);
+
 
}
 
}
// Rotates this Vector3 around the X axis
+
// Overload the [<>] operator
Function Pitch($degree)
+
// Same as above nothing special here
 +
Operator "[<>]"
 
{
 
{
        my $v1 = self::Pitch($this, $degree);
+
return VarDump($Values);
$x = $v1->$x;
+
$y = $v1->$y;
+
$z = $v1->$z;
+
unset($v1);
+
 
}
 
}
// Rotates a Vector3 around the Z axis
+
    Static Function Roll(Vec3 $v1, $degree)
+
}
 +
my $Testy = new Testy();
 +
*$Testy[] = "One";
 +
*$Testy[] = "Two";
 +
*$Testy[] = "Three";
 +
*$Testy[]! = "Zero";
 +
println( *$Testy[<>] );
 +
Unset($Testy);
 +
</syntaxhighlight>
 +
 
 +
==== Overloading [<=>] ====
 +
 
 +
<syntaxhighlight lang="sputnik">
 +
Class Testy
 +
{
 +
Operator "[<=>]"
 
{
 
{
return new Vec3
+
return array("key" => "value");
(
+
($v1->$x * Cos($degree)) - ($v1->$y * Sin($degree)),
+
($v1->$x * Sin($degree)) + ($v1->$y * Cos($degree)),
+
$v1->$z
+
);
+
 
}
 
}
// Rotates this Vector3 around the Z axis
+
Function Roll($degree)
+
}
{
+
my $Testy = new Testy();
        my $v1 = self::Roll($this, $degree);
+
printr $Testy[<=>];
$x = $v1->$x;
+
$y = $v1->$y;
+
$z = $v1->$z;
+
unset($v1);
+
}
+
// Compares the magnitude of two Vectors and returns the greater Vector3
+
Static Function Max(Vec3 $v1, Vec3 $v2)
+
{
+
if ($v1 >= $v2){return $v1;}
+
return $v2;
+
}
+
// Compares the magnitude of this and another and returns the greater Vector3
+
Function Max(Vec3 $other)
+
{
+
return self::Max($this, $other);
+
}
+
// Compares the magnitude of two Vectors and returns the lesser Vector3
+
Static Function Min(Vec3 $v1, Vec3 $v2)
+
{
+
if ($v1 <= $v2){return $v1;}
+
return $v2;
+
}
+
// Compares the magnitude of this and another and returns the lesser Vector3
+
Function Min(Vec3 $other)
+
{
+
return self::Min($this, $other);
+
}
+
    // Find the absolute value of a Vector3
+
    Static Function Abs(Vec3 $v1)
+
    {
+
        return $v1->Magnitude();
+
    }
+
    // Find the absolute value of this Vector3
+
    Function Abs()
+
    {
+
        return $this->Magnitude();
+
    }
+
/// Checks if a vector is a unit vector
+
Static Function IsUnitVector(Vec3 $v1)
+
{
+
        return Abs($v1->Magnitude() -1) <= @Double_Epsilon;
+
}
+
/// Checks if this vector is a unit vector
+
Function IsUnitVector()
+
{
+
        return Abs($this->Magnitude() -1) <= @Double_Epsilon;
+
}
+
/// Checks if two Vectors are perpendicular
+
/// Checks if two Vectors are orthogonal
+
/// Checks if one Vector3 is the Normal of the other
+
Static Function IsPerpendicular(Vec3 $v1, Vec3 $v2)
+
{
+
        return $v1->DotProduct($v2) == 0;
+
}
+
/// Checks this Vector and another are perpendicular
+
/// Checks this Vector and another  are orthogonal
+
/// Checks this Vector is the Normal of the other
+
Function IsPerpendicular(Vec3 $other)
+
{
+
return self::IsPerpendicular($this, $other);
+
}
+
/// Checks if a face normal vector represents back face
+
/// Checks if a face is visible, given the line of sight
+
Static Function IsBackFace(Vec3 $normal, Vec3 $lineOfSight)
+
{
+
        return $normal->DotProduct($lineOfSight) < 0;
+
}
+
/// Checks if a face normal vector represents back face
+
/// Checks if a face is visible, given the line of sight
+
Function IsBackFace(Vec3 $lineOfSight)
+
{
+
return self::IsBackFace($this, $lineOfSight);
+
}
+
    // Creates a look vector (Heading) of a given Yaw and Pitch
+
    Static Function GetLookVector($Yaw, $Pitch)
+
    {
+
        return new Vec3(-Sin($Yaw) * Cos($Pitch), Sin($Pitch), -Cos($Yaw) * Cos($Pitch));
+
    }
+
    /// Retuns the smallest vector possible (based on the double precision floating point structure) for you to use
+
    Static Function MinValue()
+
    {
+
        return new Vec3(@Double_Min, @Double_Min, @Double_Min);
+
    }
+
    /// Retuns the largest vector possible (based on the double precision floating point structure) for you to use
+
    Static Function MaxValue()
+
    {
+
        return new Vec3(@Double_Max, @Double_Max, @Double_Max);
+
    }
+
    /// Retuns an empty Vector3 object for you to use
+
    Static Function Zero()
+
    {
+
        return new Vec3(0.0, 0.0, 0.0);
+
    }
+
Operator "+" ($vec)
+
{
+
If ( isVarClass($vec, "vec3") )
+
{ $this->$x += $vec->$x; $this->$y += $vec->$y; $this->$z += $vec->$z; }
+
else
+
{ $this->$x += $vec; $this->$y += $vec; $this->$z += $vec; }
+
}
+
Operator "+=" ($vec)
+
{
+
If ( isVarClass($vec, "vec3") )
+
{ $this->$x += $vec->$x; $this->$y += $vec->$y; $this->$z += $vec->$z; }
+
else
+
{ $this->$x += $vec; $this->$y += $vec; $this->$z += $vec; }
+
}
+
Operator "*" ($vec)
+
{
+
If ( isVarClass($vec, "vec3") )
+
{ $this->$x *= $vec->$x; $this->$y *= $vec->$y; $this->$z *= $vec->$z; }
+
else
+
{ $this->$x *= $vec; $this->$y *= $vec; $this->$z *= $vec; }
+
}
+
Operator "*=" ($vec)
+
{
+
If ( isVarClass($vec, "vec3") )
+
{ $this->$x *= $vec->$x; $this->$y *= $vec->$y; $this->$z *= $vec->$z; }
+
else
+
{ $this->$x *= $vec; $this->$y *= $vec; $this->$z *= $vec; }
+
}
+
Operator "/" (Vec3 $vec)
+
{
+
If ( isVarClass($vec, "vec3") )
+
{ $this->$x /= $vec->$x; $this->$y /= $vec->$y; $this->$z /= $vec->$z; }
+
else
+
{ $this->$x /= $vec; $this->$y /= $vec; $this->$z /= $vec; }
+
}
+
Operator "/=" (Vec3 $vec)
+
{
+
If ( isVarClass($vec, "vec3") )
+
{ $this->$x /= $vec->$x; $this->$y /= $vec->$y; $this->$z /= $vec->$z; }
+
else
+
{ $this->$x /= $vec; $this->$y /= $vec; $this->$z /= $vec; }
+
}
+
Operator "-" (Vec3 $vec)
+
{
+
If ( isVarClass($vec, "vec3") )
+
{ $this->$x -= $vec->$x; $this->$y -= $vec->$y; $this->$z -= $vec->$z; }
+
else
+
{ $this->$x -= $vec; $this->$y -= $vec; $this->$z -= $vec; }
+
}
+
Operator "-=" (Vec3 $vec)
+
{
+
If ( isVarClass($vec, "vec3") )
+
{ $this->$x -= $vec->$x; $this->$y -= $vec->$y; $this->$z -= $vec->$z; }
+
else
+
{ $this->$x -= $vec; $this->$y -= $vec; $this->$z -= $vec; }
+
}
+
Operator "**" (Vec3 $vec)
+
{
+
If ( isVarClass($vec, "vec3") )
+
{ $this->$x **= $vec->$x; $this->$y **= $vec->$y; $this->$z **= $vec->$z; }
+
else
+
{ $this->$x **= $vec; $this->$y **= $vec; $this->$z **= $vec; }
+
}
+
Operator "**=" (Vec3 $vec)
+
{
+
If ( isVarClass($vec, "vec3") )
+
{ $this->$x **= $vec->$x; $this->$y **= $vec->$y; $this->$z **= $vec->$z; }
+
else
+
{ $this->$x **= $vec; $this->$y **= $vec; $this->$z **= $vec; }
+
}
+
Operator "%" (Vec3 $vec)
+
{
+
If ( isVarClass($vec, "vec3") )
+
{ $this->$x %= $vec->$x; $this->$y %= $vec->$y; $this->$z %= $vec->$z; }
+
else
+
{ $this->$x %= $vec; $this->$y %= $vec; $this->$z %= $vec; }
+
}
+
Operator "%=" (Vec3 $vec)
+
{
+
If ( isVarClass($vec, "vec3") )
+
{ $this->$x %= $vec->$x; $this->$y %= $vec->$y; $this->$z %= $vec->$z; }
+
else
+
{ $this->$x %= $vec; $this->$y %= $vec; $this->$z %= $vec; }
+
}
+
// Compare two Vectors for equality.
+
Operator "==" (Vec3 $vec)
+
{
+
        return
+
        (
+
            Abs($this->$x - $vec->$x) <= @Double_Epsilon &&
+
            Abs($this->$y - $vec->$y) <= @Double_Epsilon &&
+
            Abs($this->$z - $vec->$z) <= @Double_Epsilon
+
        );
+
}
+
// Compare two Vectors for not equality.
+
Operator "!=" (Vec3 $vec)
+
{
+
return !($this == $vec);
+
}
+
// Compare the magnitude of two Vectors (less than)
+
Operator "<" (Vec3 $vec)
+
{
+
        return $this->SumComponentSqrs() < $vec->SumComponentSqrs();
+
}
+
// Compare the magnitude of two Vectors (greater than)
+
Operator ">" (Vec3 $vec)
+
{
+
        return $this->SumComponentSqrs() > $vec->SumComponentSqrs();
+
}
+
// Compare the magnitude of two Vectors (less than or equal to)
+
Operator "<=" (Vec3 $vec)
+
{
+
        return $this->SumComponentSqrs() <= $vec->SumComponentSqrs();
+
}
+
// Compare the magnitude of two Vectors (greater than or equal to)
+
Operator ">=" (Vec3 $vec)
+
{
+
        return $this->SumComponentSqrs() >= $vec->SumComponentSqrs();
+
}
+
// Compare the magnitude of two Vectors (greater than or lower than)
+
Operator "<>" (Vec3 $vec)
+
{
+
return $this < $vec || $this > $vec;
+
}
+
};
+
 
</syntaxhighlight>
 
</syntaxhighlight>
 +
 +
[[Category:Classes]]

Latest revision as of 18:39, 21 September 2015

NOTE - Everything listed on this page DOES work even tho there are not examples for everything they do indeed work if you wish to try it out.

Rather unconventionally Sputnik requires a ; to end a class statement although not a limitation of the parser but I just thought it looked cool.

Regular class :

Class <name>
{
	statements
	...
	functions
	...
	operator overloads
	...
	casting overloads
	...
}

Extender class that adds functions and features to an existing class :

Class extends <name>
{
	statements
	...
	functions
	...
	operator overloads
	...
	casting overloads
	...
}

Inheritance class that inherits functions and features from an existing class :

Class <name> extends <parentname>
{
	statements
	...
	functions
	...
	operator overloads
	...
	casting overloads
	...
}

Inheritance class that inherits functions and features from multiple existing classes :

Class <name> extends <parentname>, <parentname>, <parentname>...
{
	statements
	...
	functions
	...
	operator overloads
	...
	casting overloads
	...
}

Contents

Description

Features

Statements

Variables

Static Variables

Properties

A property works like a normal variable however instead of returning or setting a variable it executes code when you try get/set the variable take the example below

Class cat
{
	# Define a new property
	my $Test 
	{ # Rquired block for it
		get # Define the GET accessor
		{ # Its block and code to execute
			say "Getting the value";
			return $Test;
		}
		set # Define the SET accessor
		{ # Its block and code to execute
			say "Setting to $value";
			$Test = $value;
		}
	}
}
 
$a = new cat();
$a->$Test = 77;
say "Value: " . $a->$Test;
 
# Prints
# Setting to 77
# Getting the value
# Value: 77

Inside the GET or SET block the property name becomes a variable so $Test is a property but inside the GET or SET it is a variable like any other and you can get/set to it of course you can choose to ignore the variable entirely and do anything you want inside the GET/SET.

Of note :

Abstract/Override Properties

Works exactly same as property above but this time it will be marked as abstract so any class inheriting our class must implement a property by the same name as this one.

To implement it you must use the override keyword as shown in the example below.

Class cat
{
	Abstract my $ID { }
}
 
Class foo extends cat
{
	my $_id;
	override my $ID
	{
		get
		{
			return ++$_id;
		}
	}
}
 
$a = new foo();
say "UniqueID: " . $a->$ID;
say "UniqueID: " . $a->$ID;
say "UniqueID: " . $a->$ID;
say "UniqueID: " . $a->$ID;
say "UniqueID: " . $a->$ID;
# Prints
# UniqueID: 1
# UniqueID: 2
# UniqueID: 3
# UniqueID: 4

Of note :

Functions

Public Functions

By default all functions are public and there is no *Public* keyword since they are automatically public.

Private Functions

By default all functions are public and there is no *Public* keyword since they are automatically public however if you want a function to be private you must insert the "Private" keyword before the function.

Once private is defined you can call the function by name inside the class and by using $this-> but you can't call the function from outside the class this will prevent people from using functions that could cause functions such as internal functions that must only be used by the class itself.

Class Test
{
	Function __Construct()
	{
		say "Made...";
	}
	Function Testy()
	{
		say "Testy";
		Foo("Called from class");
		$this->Foo("Called from class THIS");
	}
	Private Function Foo($value)
	{
		say "Foo: $value";
	}
}
 
$a = new Test();
$a->Testy();
$a->Foo("called from pointer"); # Fails cannot access private function
# Prints
# Made...
# Testy
# Foo: Called from class
# Foo: Called from class THIS
 
# then throws an exception

Abstract/Override Functions

Works exactly same as functions above but this time it will be marked as abstract so any class inheriting our class must implement a function by the same name as this one.

To implement it you must use the override keyword as shown in the example below.

// Define a class we will inherit
Class EngineInfo
{
	// define an abstract function
	abstract Function Engine() { }
	// define two abstract properties
	Abstract my $GearVer { }
	Abstract my $GearBox { }
}
 
// Define the final class
Class Car extends EngineInfo
{
	// override the abstract function Engine()
	override Function Engine()
	{
		return "V8";
	}
	// streamlined property
	override my $GearVer { get { return "1.0"; } }
	// expanded property
	override my $GearBox
	{
		get 
		{
			return "12Gears"; 
		} 
	}
}
 
my $c = new Car();
say "Engine: " . $c->Engine();
say "GearVer: " . $c->$GearVer;
say "GearBox: " . $c->$GearBox;
// PRINTS
// Engine: V8
// GearVer: 1.0
// GearBox: 12Gears

Of note :

Static Functions

Static functions can't be private.

Magic Functions

A magic function is basically a function that starts with __ and gets executed when a specific core function is used with the class variable in its context here is an example

Class Test
{
	my $data = array(); # A simple array to hold our data
	Function __Construct() # Is called when you do new ClassName()
	{
		say "__Construct() called";
	}
	Function __Destruct() # Is called when you do unset($class)
	{
		say "__Destruct() called";
	}
	Function __Set($key, $value) # Is called when you do $class['key'] = 
	{
		say "__Set() called with key '$key' and value '$value'";
		$data[$key] = $value;
		return true;
	}
	Function __Get($key) # Is called when you do $class['key']
	{
		say "__Get() called with key '$key'";
		return $data[$key];
	}
	Function __Unset($key) # Is called when you do unset($class['key'])
	{
		say "__Unset() called with key '$key'";
		unset($data[$key]);
		return true;
	}
	Function __IsSet($key) # Is called when you do isset($class['key']) or isset($class)
	{
		# The key will be NULL if this was called using isset($class)
		say "__IsSet() called with key '$key'";
		return isset($data[$key]);
	}
	Function __Call() # Is called when you do $class() and try use it as a function
	{
		say "Hello from _Call"; # we could use params and return a value
	}
	Function PrintAll() # Just print the current data the class holds
	{
		printr $data;
	}
}
 
$a = new Test();
$a(); # Treat the class as a function
$a['Foo'] = "Bar"; # Set key 'Foo' to 'Bar'
$a['Cat'] = "Meow"; # Set key 'Cat' to 'Meow'
say "Foo is: " . $a['Foo']; # Get key 'Foo'
say isset($a); # Check if the class itself is set
say isset($a['Foo']); # Check if the key 'Foo' is set
$a->PrintAll(); # Print what the class contains
unset($a['Foo']); # Unset the key 'Foo'
$a->PrintAll(); # Print what the class contains
unset($a); # dispose of the class
printr(vardump($a)); # NULL

Magic Functions/Properties (others)

These magic functions and properties are used by other core functions that are nothing to do with classes directly (usually)but will work classes in a special way if you extend or do something that it requires.

Operator Overloads

Cast Overloads

Embedding

A class can be embedded inside an IF statement (or any statement) so that it can be created on a conditional for example:

// Check if the class already exists and
// if it does already exists don't create it
if (!ClassExists("Cat"))
{
	// Create the class using the Embedded keyword
	Embedded Class Cat
	{
		Function __construct()
		{
			say "testy!";
		}
	}; // note ; is required here
}
$a = new cat();
// PRINTS
// testy!

Remarks

Examples

Creating Classes

Using Classes

Inheriting Classes

Extending Classes

Multiple Inheritance Classes

Sputnik supports multiple inheritance in a rather unique and powerful way.

// Define a class we will inherit
Class EngineInfo
{
	// define an abstract function
	abstract Function Engine() { }
	// define two abstract properties
	Abstract my $GearVer { }
	Abstract my $GearBox { }
	// define a normal Function
	// the final class will inherit this
	// and since it is not an abstract it will
	// appear as if it was literally inside the
	// original
	Function EngineTest()
	{
		say "Testing engine...";
	}
}
 
// Define another class we will inherit
Class CarColour
{
	// define an abstract property
	Abstract my $Colour { }
	// define a normal Function
	// the final class will inherit this
	// and since it is not an abstract it will
	// appear as if it was literally inside the
	// original
	Function ColourTest()
	{
		say "Testing colours...";
	}
}
 
// Define the final class
// We will multiple inherit both 
// EngineInfo AND CarColour
Class Car extends EngineInfo, CarColour
{
	// override the abstract function Engine()
	override Function Engine()
	{
		return "V8";
	}
	// streamlined properties
	override my $GearVer { get { return "1.0"; } }
	override my $Colour { get { return "Red"; } }
	// expanded property
	override my $GearBox
	{
		get 
		{
			return "12Gears"; 
		} 
	}
}
 
my $c = new Car();
say "Colour: " . $c->$Colour;
say "Engine: " . $c->Engine();
say "GearVer: " . $c->$GearVer;
say "GearBox: " . $c->$GearBox;
$c->EngineTest();
$c->ColourTest();
// PRINTS
// Colour: Red
// Engine: V8
// GearVer: 1.0
// GearBox: 12Gears
// Testing engine...
// Testing colours...

Cast Overloading

Sputnik allows you to overload all the castings such as (int)value etc this is useful if you have a class that uses multiple variables and you would like them all added together each time you use (float)$myclass (or any cast you are doing such as (string) also it will run the cast if the function you are using wants to convert the variable into a string such as print()).

Overloading Cast: null

Overloading Cast: char

Overloading Cast: byte

Overloading Cast: sbyte

Overloading Cast: uint16

Overloading Cast: uint32

Overloading Cast: uint64

Overloading Cast: int16

Overloading Cast: int32

Overloading Cast: int64

Overloading Cast: intptr

Overloading Cast: uintptr

Overloading Cast: long

Overloading Cast: float

Overloading Cast: double

Overloading Cast: string

Class Account
{
	my $Name;
	my $Credits;
	Function __construct($Name = "", $Credits = 0)
	{
		$this->$Name = $Name;
		$this->$Credits = $Credits;
	}
	Operator "string" // This will be done whenever somebody uses (string)$ourclass
	{
		return "Account '$Name' Credits '$Credits'";
	}
}
$nacc = New Account("FoX", 777);
println( (string)$nacc ); // Prints Account 'FoX' Credits '777'

Overloading Cast: binary

Operator Overloading

Sputnik allows you to overload a vast array of operators on your classes this is very helpful for all kinds of things example imagine you have a class that contains 3 varibles X Y and Z and you want to add another classes variables X Y Z onto yours creating a += operator you could quite simply do just that example:

Without overloads:

$vec1->$x += $vec2->$x;
$vec1->$y += $vec2->$y;
$vec1->$z += $vec2->$z;

As you can see we needed 3 lines of code to do that and doing this over and over in many places of the code will cause a lot of repeat code also what if later we decide we need to add a third variable after z? We would need to go back and change everything...

However if we overload the += operator we can do this:

$vec1 += $vec2;

See how much easier that was? And if we add a new variable or even several later we can just fix our single += overload function and it will automatically fix every single peice of += in your code that uses it.

See the examples below for what you can overload and exactly how to do just that.

Overloading =

You can overload the = such as $a = 10;

However you must remember once this is overloaded you cant change the variable by simply $a = null;

Since it will just use the overloaded function instead of setting the variable.

To delete a variable you have given = casting to you must use unset($a); instead.

Overloading +=

Overloading -=

Overloading *=

Overloading **=

Overloading /=

Overloading %=

Overloading .=

Overloading ..=

Overloading ^=

Overloading &=

Overloading |=

Overloading >>=

Overloading <<=

Overloading >>>=

Overloading <<<=

Overloading &&=

Overloading ||=

Overloading |

Overloading ^

Overloading &

Overloading +

Overloading -

Overloading *

Overloading **

Overloading /

Overloading %

Overloading .

Overloading <<

Overloading >>

Overloading <<<

Overloading >>>

Overloading ++

Class Vec3
{
	my $x = 0;
	my $y = 0;
	my $z = 0;
	Function __construct($x1 = 0, $y1 = 0, $z1 = 0)
	{
		$this->$x = $x1;
		$this->$y = $y1;
		$this->$z = $z1;
	}
	Operator "++"
	{
		$this->$x++;
		$this->$y++;
		$this->$z++;
	}
}
$cat1 = new Vec3(10, 20, 30);
println("BEFORE ++");
println("Class variable X: " . $cat1->$x);
println("Class variable Y: " . $cat1->$y);
println("Class variable Z: " . $cat1->$z);
$cat1++;
println("AFTER ++");
println("Class variable X: " . $cat1->$x);
println("Class variable Y: " . $cat1->$y);
println("Class variable Z: " . $cat1->$z);
// Prints
// BEFORE ++
// Class variable X: 10
// Class variable Y: 20
// Class variable Z: 30
// AFTER ++
// Class variable X: 11
// Class variable Y: 21
// Class variable Z: 31

Overloading --

Class Vec3
{
	my $x = 0;
	my $y = 0;
	my $z = 0;
	Function __construct($x1 = 0, $y1 = 0, $z1 = 0)
	{
		$this->$x = $x1;
		$this->$y = $y1;
		$this->$z = $z1;
	}
	Operator "--"
	{
		$this->$x--;
		$this->$y--;
		$this->$z--;
	}
}
$cat1 = new Vec3(10, 20, 30);
println("BEFORE --");
println("Class variable X: " . $cat1->$x);
println("Class variable Y: " . $cat1->$y);
println("Class variable Z: " . $cat1->$z);
$cat1--;
println("AFTER --");
println("Class variable X: " . $cat1->$x);
println("Class variable Y: " . $cat1->$y);
println("Class variable Z: " . $cat1->$z);
// Prints
// BEFORE --
// Class variable X: 10
// Class variable Y: 20
// Class variable Z: 30
// AFTER --
// Class variable X: 9
// Class variable Y: 19
// Class variable Z: 29

Overloading ==

Overloading ===

Overloading !=

Overloading !==

Overloading <

Overloading <=

Overloading >

Overloading >=

Overloading <>

Overloading eq

Overloading eqi

Overloading neq

Overloading neqi

Overloading cmp

Overloading cmpi

Overloading lt

Overloading gt

Overloading le

Overloading ge

Overloading lti

Overloading gei

Overloading lei

Overloading gei

Overloading lg

Overloading lgi

Overloading ||

Overloading &&

Overloading []

Class Testy
{
	my $Values;
	Function __Construct()
	{
		$this->$Values = array();
		println("A new Testy() class was made");
	}
	Function __Deconstruct()
	{
		$this->$Values = array();
		println("A Testy() class was destroyed");
	}
	Function PrintMe()
	{
		println("Values BELOW");
		printr($Values);
		println("Values ABOVE");
	}
	// Overload the [] operator
	// Note that you don't get the value that is going to
	// to the [] this is because Sputnik doesn't yet know
	// what is going inside it however it knows the array
	// must be extended to allow something to go inside it.
	// So we simply extend the array and return a pointer to it
	// This will allow the array element to be set later
	Operator "[]"
	{
		// & means return a pointer to new index
		return &$this->$Values[];
	}
 
}
 
my $Testy = new Testy();
// Now we use use the new index that was returned and place stuff in it
// However it is being returned as a POINTER so to make use of it we
// resolve it back into a variable using the * symbol.
// * Causes a pointer to become as if it was the actual object.
*$Testy[] = "One";
*$Testy[] = "Two";
*$Testy[] = "Three";
$Testy->PrintMe();
Unset($Testy);

Overloading []!

Class Testy
{
	my $Values;
	Function __Construct()
	{
		$this->$Values = array();
		println("A new Testy() class was made");
	}
	Function __Deconstruct()
	{
		$this->$Values = array();
		println("A Testy() class was destroyed");
	}
	Function PrintMe()
	{
		println("Values BELOW");
		printr($Values);
		println("Values ABOVE");
	}
	// Overload the [] operator
	// Note that you don't get the value that is going to
	// to the [] this is because Sputnik doesn't yet know
	// what is going inside it however it knows the array
	// must be extended to allow something to go inside it.
	// So we simply extend the array and return a pointer to it
	// This will allow the array element to be set later
	Operator "[]"
	{
		// & means return a pointer to new index
		return &$this->$Values[];
	}
	// Overload the []! operator
	// Same as above nothing special here
	Operator "[]!"
	{
		return &$this->$Values[]!;
	}	
}
my $Testy = new Testy();
// Now we use use the new index that was returned and place stuff in it
// However it is being returned as a POINTER so to make use of it we
// resolve it back into a variable using the * symbol.
// * Causes a pointer to become as if it was the actual object.
*$Testy[] = "One";
*$Testy[] = "Two";
*$Testy[] = "Three";
*$Testy[]! = "Zero";
$Testy->PrintMe();
Unset($Testy);

Overloading [<>]

Class Testy
{
	my $Values;
	Function __Construct()
	{
		$this->$Values = array();
		println("A new Testy() class was made");
	}
	Function __Deconstruct()
	{
		$this->$Values = array();
		println("A Testy() class was destroyed");
	}
	// Overload the [] operator
	// Note that you dont get the value that is going to
	// to the [] this is because Sputnik doesnt yet know
	// what is going inside it however it knows the array
	// must be extended to allow something to go inside it.
	// So we simply extend the array and return a pointer to it
	// This will allow the array element to be set later
	Operator "[]"
	{
		return &$this->$Values[];
	}
	// Overload the []! operator
	// Same as above nothing special here
	Operator "[]!"
	{
		return &$this->$Values[]!;
	}
	// Overload the [<>] operator
	// Same as above nothing special here
	Operator "[<>]"
	{
		return VarDump($Values);
	}
 
} 
my $Testy = new Testy();
*$Testy[] = "One";
*$Testy[] = "Two";
*$Testy[] = "Three";
*$Testy[]! = "Zero";
println( *$Testy[<>] );
Unset($Testy);

Overloading [<=>]

Class Testy
{
	Operator "[<=>]"
	{
		return array("key" => "value");
	}
 
}
my $Testy = new Testy();
printr $Testy[<=>];
Personal tools
Namespaces
Variants
Actions
Navigation
Toolbox