"Sputnik" help  
Sputnik Help
Rule Magic

Description

This demonstrates how to create a function that allows a class magic function of the same name to override it.

Before reading this section make sure to read all User Functions and understand it.

Remarks

The Magic rule in Sputnik enables the creation of custom magic functions that override the behavior of existing functions within classes. When a function is flagged with "mf" for magic, it automatically allows the creation of a corresponding "__NAME" function, where "NAME" is the name of the original function. This "__NAME" function can be defined within a class to execute instead of the original function when the class is used.

For instance, if a function named "Bar" is flagged with "mf" for magic, the class containing it can define a "__Bar" function, which will execute instead of "Bar" when invoked on an instance of that class. This feature provides developers with a convenient mechanism to customize and extend the behavior of functions within their classes.

Additionally, the "mfe" variant of the magic rule offers further flexibility by providing access to special variables: "@HasMagic" and "@Magic". If "@Magic" is defined, it contains the return value of the magic function, and "@HasMagic" is set to true. This allows the magic function to execute the original method after performing custom logic, expanding the possibilities for handling function overrides.

In summary, the "Rule Magic" in Sputnik empowers developers to create custom magic functions within classes, enhancing the flexibility and extensibility of the language's object-oriented capabilities.

Related

User Functions

Example

Example of usage:

Class Foo
{
    my $Fooby = "Barby";
    Function __Bar($a, $b)
    {
        return "Bar = $a($b) [$Fooby]";
    }
}

"mf" Function Bar($v)
{
    return "FooBar = $v";
}

my $foo = new foo();
my $bar = "Cat";

say Bar($foo, 777, 42);
say Bar($bar);

// PRINTS
// Bar = 777(42) [Barby]
// FooBar = Cat

In this code snippet, we create a function named Bar with a magic rule. This enables us to define a class function with the same name but prefixed with __, such as __Bar, which acts as a magic function. When we call the original function with an instance of the class, it automatically executes the corresponding magic function, allowing for customized behavior specific to instances of the class.

Class Foo
{
    my $Fooby = "Barby";
    Function __Bar($a, $b)
    {
        return "Bar$a($b) [$Fooby]";
    }
}

"mfe" Function Bar($v)
{
    if (@HasMagic)
    {
        if (defined(@Magic))
            return "Magic = " . @Magic;
        else
            return "Magic return missing!";
    }
    return "FooBar = $v";
}

my $foo = new foo();
my $bar = "Cat";

say Bar($foo, 777, 42);
say Bar($bar);

// PRINTS
// Magic = Bar777(42) [Barby]
// FooBar = Cat

In this code snippet, we create a function named Bar with a magic execution rule. This enables us to define a class function with the same name but prefixed with __, such as __Bar, which acts as a magic function. When we call the original function with an instance of the class, it automatically executes the corresponding magic function, But then it immediately executes the Bar function after the __Bar is called, allowing seamless integration of custom logic with the original function. If the magic function returns a value, it can be accessed using the @Magic macro. We know if we are being executed immediately after the __Foo magic function sinec the @HasMagic will be set to true.

A practical example of the "mf" rule:

Class Coodski
{
    my $X;
    my $Y;
    Function __Construct($x, $y)
    {
        @this->$X = $x;
        @this->$Y = $y;
    }
    Function __ToShapen("..." $values)
    {
    return [count($values) + 2, $X, $Y, **$values];
    }
}

"mf" Function ToShapen("..." $values)
{
    return [count($values), **$values];
}

printr ToShapen("Hello");
// PRINTS
// Array
// (
//     [0] => 1
//     [1] => Hello
// )

printr ToShapen("Hello", 1221, 777);
// PRINTS
// Array
// (
//     [0] => 3
//     [1] => Hello
//     [2] => 1221
//     [3] => 777
// )

my $a = new Coodski(10, 20);
printr ToShapen($a, "Hello", 1377);
// PRINTS
// Array
// (
//     [0] => 4
//     [1] => 10
//     [2] => 20
//     [3] => Hello
//     [4] => 1377
// )

In this practical example showcasing the "mf" rule in action. We have a function called ToShapen that takes its arguments and returns an array containing those arguments, prefixed by the number of arguments provided. Think of it like an old Pascal string. However, the twist here is that the function allows for class overrides. In this example, the Coodski class provides an override for ToShapen. Notice how the class expands the arguments as usual but also includes its own variables in the returned array. This allows the class to return a value that users of the ToShapen function expect, but in a way that's beneficial for the class itself.

A practical example of the "mfe" rule:

Class Coodski
{
    my $X;
    my $Y;
    Function __Construct($x, $y)
    {
        @this->$X = $x;
        @this->$Y = $y;
    }
    Function __ToShapen()
    {
    return [2, $X, $Y];
    }
}

"mfe" Function ToShapen("..." $values)
{
    if (@HasMagic)
    {
        my $subValues = Slice($values, 1); // clip off the class instance variable
        my $subMagic = Slice(@Magic, 1); // clip off the count from the magic function
        return [count($subValues) + count($subMagic) + 1, **$subValues, **$subMagic, 1337];
    }
    return [count($values), **$values];
}

printr ToShapen("Hello");
// PRINTS
// Array
// (
//     [0] => 1
//     [1] => Hello
// )

printr ToShapen("Hello", 1221, 777);
// PRINTS
// Array
// (
//     [0] => 3
//     [1] => Hello
//     [2] => 1221
//     [3] => 777
// )

my $a = new Coodski(10, 20);
printr ToShapen($a, "Hello", 1377);
// PRINTS
// Array
// (
//     [0] => 5
//     [1] => Hello
//     [2] => 1377
//     [3] => 10
//     [4] => 20
//     [5] => 1337
// )

In this example, we showcase a practical use of the "mfe" flag in defining the ToShapen function. When invoked, ToShapen executes after the __ToShapen magic function due to the "mfe" flag. It checks for the presence of a magic function execution using @HasMagic and processes the arguments accordingly. After removing the class instance and magic function count, ToShapen concatenates and manipulates the remaining values to produce the desired output, providing enhanced flexibility and control over function behavior and return values.

In Summary

This ability to create custom magic functions in Sputnik is very powerful, allowing developers to define specialized behavior for class instances. By leveraging magic functions prefixed with __, users can seamlessly integrate custom logic with the original function. With the "mfe" rule applied, magic functions can also execute immediately before the original function, providing even more flexibility in modifying behavior. This feature enhances the expressiveness and flexibility of the Sputnik language, empowering developers to create more dynamic and tailored solutions.


Contact
Cheryl (uberfox@hotmail.com)
Homepage
http://ubersoft.org