"Sputnik" help  
Sputnik Help
Language Reference - Datatypes - Slicing Assignments

Slicing Assignments

Make sure to read Slicing first so you understand what slicing is and how it works since we are not going to go over that again here and we will just assume you already know..

Sputnik introduces a sophisticated feature known as slicing assignments, empowering users to precisely modify specific elements or segments within strings, binary data, and arrays. This capability streamlines data manipulation tasks, offering a powerful and flexible approach.

A Fundamental Understanding
Before harnessing the full potential of slicing assignments, it's imperative to comprehend the fundamentals of slicing. Slicing, in general, involves extracting portions of a sequence based on specified indices or ranges. If you need to delve into the basics of slicing, please refer to the Slicing documentation for a comprehensive overview.

A Closer Look at Slicing Assignments
Slicing assignments extend the utility of slicing by enabling targeted modifications within different data structures:

Strings:
Slicing assignments allow the precise replacement or alteration of specific substrings within a string. This feature proves invaluable when dealing with complex textual data, offering an elegant solution for efficient text processing.

Binary Data:
Binary sequences can undergo seamless modification using slicing assignments. This capability is particularly beneficial in scenarios where precise byte-level adjustments are required, such as in cryptographic operations or binary data processing.

Arrays:
For arrays, slicing assignments provide a concise and expressive means to update elements or segments. Whether you're working with numeric arrays or complex data structures, slicing assignments enhance code readability and maintainability.

Advantages of Slicing Assignments

Unlocking Potential with Sputnik
Slicing assignments are a testament to Sputnik's commitment to providing powerful and user-friendly features. As you explore and incorporate slicing assignments into your code, you embark on a journey of enhanced data manipulation capabilities, ultimately contributing to more efficient and readable code. Discover the potential within your data structures with Sputnik's slicing assignments.


Array Examples

Replacing array elements from [1] to [2] with "squigs":

my $a = ["cat", "dog", "fox", "rabbit", "turtle"];
$a[1:3] = "squigs";
printr $a;
// PRINTS
// Array
// (
//     [0] => cat
//     [1] => squigs
//     [2] => squigs
//     [3] => rabbit
//     [4] => turtle
// )

Replacing array elements from [1] to [2] with "squigs" and "rats":

my $a = ["cat", "dog", "fox", "rabbit", "turtle"];
$a[1:3] = ["squigs", "rats"];
printr $a;
// PRINTS
// Array
// (
//     [0] => cat
//     [1] => squigs
//     [2] => rats
//     [3] => rabbit
//     [4] => turtle
// )

Modifying array elements from [1] to [2] by adding 5 to first then 6 to second:

my $a = [10, 20, 30, 40, 50];
$a[1:3] += [5, 6];
printr $a;
// PRINTS
// Array
// (
//     [0] => 10
//     [1] => 25
//     [2] => 36
//     [3] => 40
//     [4] => 50
// )

Modifying all the array elements by prefixing color names to them:

my $a = ["Cat", "Dog", "Fox"];
$a[:] ..= ["Red", "Green", "Blue"];
printr $a;
// PRINTS
// Array
// (
//     [0] => RedCat
//     [1] => GreenDog
//     [2] => BlueFox
// )

Modifying array elements from [1] to [2] by prefixing color names "Red" to first then "Blue" to second:

my $a = ["Cat", "Dog", "Fox", "Squirrl", "Racoon"];
$a[1:3] ..= ["Red", "Blue"];
printr $a;
// PRINTS
// Array
// (
//     [0] => Cat
//     [1] => RedDog
//     [2] => BlueFox
//     [3] => Squirrl
//     [4] => Racoon
// )

Modifying all the array elements turning them all into "rabbit":

my $a = ["cat", "dog", "fox"];
$a[:] = "rabbit";
printr $a;
// PRINTS
// Array
// (
//     [0] => rabbit
//     [1] => rabbit
//     [2] => rabbit
// )

Modifying all the array elements turning them into "red" "blue" "green" respectively:

my $a = ["cat", "dog", "fox"];
$a[:] = ["red", "green", "blue"];
printr $a;
// PRINTS
// Array
// (
//     [0] => red
//     [1] => green
//     [2] => blue
// )

We can kinda do columns like so:

my $a = [[1,2],[3,4],[5,6],[7,8]];
$a[1:3] = [[10, 20], [30, 40]];
ASSERT(1, $a == ([[1,2],[10,20],[30,40],[7,8]]));
printr $a;

// PRINTS
// Array
// (
//     [0] => Array
//         (
//             [0] => 1
//             [1] => 2
//         )
//     [1] => Array
//         (
//             [0] => 10
//             [1] => 20
//         )
//     [2] => Array
//         (
//             [0] => 30
//             [1] => 40
//         )
//     [3] => Array
//         (
//             [0] => 7
//             [1] => 8
//         )
// )
Of course see the columns section below for the proper way to do this.

Another really powerful feature is the ability to use Code Blocks on the slices:

my $a = [1, 2, 3, 4, 5, 6];
$a[:] = {{ return $a << 1; }};
printr $a;
// PRINTS
// Array
// (
//     [0] => 2
//     [1] => 4
//     [2] => 6
//     [3] => 8
//     [4] => 10
//     [4] => 12
// )


my $a = [1, 2, 3, 4, 5, 6];
$a[1:3] = {{ return $a << 1; }};
printr $a;
// PRINTS
// Array
// (
//     [0] => 1
//     [1] => 4
//     [2] => 6
//     [3] => 4
//     [4] => 5
//     [4] => 6
// )

my $a = [1, 2, 3, 4, 5, 6];
$a[:] *= {{ return $a << 1; }};
printr $a;
// PRINTS
// Array
// (
//     [0] => 2
//     [1] => 8
//     [2] => 18
//     [3] => 32
//     [4] => 50
//     [4] => 72
// )


my $a = [1, 2, 3, 4, 5, 6];
$a[1:3] *= {{ return $a << 1; }};
printr $a;
// PRINTS
// Array
// (
//     [0] => 1
//     [1] => 8
//     [2] => 18
//     [3] => 4
//     [4] => 5
//     [4] => 6
// )

Of course we can do Function References too:

Function OpSlicer($a, $idx)
{
    return $a << 1;
}

my $a = [1, 2, 3, 4, 5, 6];
$a[:] = &OpSlicer;
printr $a;
// PRINTS
// Array
// (
//     [0] => 2
//     [1] => 4
//     [2] => 6
//     [3] => 8
//     [4] => 10
//     [4] => 12
// )


my $a = [1, 2, 3, 4, 5, 6];
$a[1:3] = &OpSlicer;
printr $a;
// PRINTS
// Array
// (
//     [0] => 1
//     [1] => 4
//     [2] => 6
//     [3] => 4
//     [4] => 5
//     [4] => 6
// )

my $a = [1, 2, 3, 4, 5, 6];
$a[:] *= FuncRef(id OpSlicer);
printr $a;
// PRINTS
// Array
// (
//     [0] => 2
//     [1] => 8
//     [2] => 18
//     [3] => 32
//     [4] => 50
//     [4] => 72
// )


my $a = [1, 2, 3, 4, 5, 6];
$a[1:3] *= FuncRef(id OpSlicer);
printr $a;
// PRINTS
// Array
// (
//     [0] => 1
//     [1] => 8
//     [2] => 18
//     [3] => 4
//     [4] => 5
//     [4] => 6
// )

The ability to use code blocks and function references in slicing assignments in Sputnik elevates the language's array manipulation capabilities to unprecedented heights. This feature empowers developers to seamlessly integrate custom logic, enabling dynamic transformations of array elements based on sophisticated calculations or external functions. By incorporating code blocks and function references into the slicing assignments, Sputnik facilitates a level of expressiveness and flexibility that goes beyond traditional array manipulation paradigms. This innovation not only streamlines the syntax but also opens up a realm of possibilities for creating more efficient and customizable algorithms in array processing.

Sputnik's array slicing assignments provide a versatile and efficient means to dynamically alter specific elements or ranges within arrays. This feature enables precise and expressive array manipulations, allowing developers to tailor and transform arrays with ease. By leveraging slicing, programmers can achieve targeted modifications, from replacing elements to applying uniform changes across the array. This capability enhances code readability and conciseness, fostering a more powerful and flexible array manipulation experience


Array (Column Mode) Examples

Modify the last 3 elements in every column by setting them all to 10:

my $a = [[1,2,3,4,5,6],[7,8,9,10,11,12]];
$a[:,3:] = 10;
printr $a;
// PRINTS
// Array
// (
//     [0] => Array
//         (
//             [0] => 1
//             [1] => 2
//             [2] => 3
//             [3] => 10
//             [4] => 10
//             [5] => 10
//         )
//     [1] => Array
//         (
//             [0] => 7
//             [1] => 8
//             [2] => 9
//             [3] => 10
//             [4] => 10
//             [5] => 10
//         )
// )

Modify the last 3 elements in every column by setting them all to 11 22 33 44 55 66 respectively using a single array to be unpacked:

my $a = [[1,2,3,4,5,6],[7,8,9,10,11,12]];
$a[:,3:] = [11, 22, 33, 44, 55, 66];
printr $a;
// PRINTS
// Array
// (
//     [0] => Array
//         (
//             [0] => 1
//             [1] => 2
//             [2] => 3
//             [3] => 11
//             [4] => 22
//             [5] => 33
//         )
//     [1] => Array
//         (
//             [0] => 7
//             [1] => 8
//             [2] => 9
//             [3] => 44
//             [4] => 55
//             [5] => 66
//         )
// )

Modify the last 3 elements in every column by setting them all to 11 22 33 and 100 110 120 respectively using a columned array:

my $a = [[1,2,3,4,5,6],[7,8,9,10,11,12]];
$a[:,3:] = [[44, 55, 66], [100, 110, 120]];
printr $a;
// PRINTS
// Array
// (
//     [0] => Array
//         (
//             [0] => 1
//             [1] => 2
//             [2] => 3
//             [3] => 44
//             [4] => 55
//             [5] => 66
//         )
//     [1] => Array
//         (
//             [0] => 7
//             [1] => 8
//             [2] => 9
//             [3] => 100
//             [4] => 110
//             [5] => 120
//         )
// )

Modify the last 3 elements in every column by += on them using columned array:

my $a = [[1,2,3,4,5,6],[7,8,9,10,11,12]];
$a[:,3:] += [[44, 55, 66], [100, 110, 120]];
ASSERT(1, $a == ([[1,2,3,48,60,72],[7,8,9,110,121,132]]));
printr $a;
// PRINTS
// Array
// (
//     [0] => Array
//         (
//             [0] => 1
//             [1] => 2
//             [2] => 3
//             [3] => 48
//             [4] => 60
//             [5] => 72
//         )
//     [1] => Array
//         (
//             [0] => 7
//             [1] => 8
//             [2] => 9
//             [3] => 110
//             [4] => 121
//             [5] => 132
//         )
// )

Modify the last 3 elements in every column by += on them using a single array to be unpacked:

my $a = [[1,2,3,4,5,6],[7,8,9,10,11,12]];
$a[:,3:] += [44, 55, 66, 100, 110, 120];
printr $a;
// PRINTS
// Array
// (
//     [0] => Array
//         (
//             [0] => 1
//             [1] => 2
//             [2] => 3
//             [3] => 48
//             [4] => 60
//             [5] => 72
//         )
//     [1] => Array
//         (
//             [0] => 7
//             [1] => 8
//             [2] => 9
//             [3] => 110
//             [4] => 121
//             [5] => 132
//         )
// )

In Sputnik's array slice assign column mode, users can efficiently manipulate multiple elements across columns. The flexibility of column mode is exemplified in various scenarios:

Setting Values:
Users can set the any elements in any column to a specific value, such as setting them all to 10. This allows for quick and concise modification of data across multiple columns.

Unpacking Arrays:
Column mode supports unpacking arrays, enabling users to set values in a concise manner. For instance, assigning values of 11, 22, 33, 44, 55, 66 to the last three elements in each column using a single array showcases the efficiency of this feature.

Columned Arrays:
Aalso supports columned arrays, providing a structured way to set values. Users can efficiently set different values for the any elements in every column, enhancing the organization and readability of the code.

Compound Assignments:
For more complex operations, users can perform compound assignments in column mode. The example demonstrates adding values from a columned array to the corresponding elements, showcasing the conciseness and power of this feature.

Overall, array slice assign column mode in Sputnik enhances code readability and conciseness, enabling users to efficiently perform operations across multiple columns with ease


String Examples

Changing an entire string to 'Z's;

my $a = "Computer";
$a[:] = 'Z';
printr $a;
// PRINTS
// ZZZZZZZZ

Changing the second to third character of the string to Z and X:

my $a = "Computer";
$a[1:3] = ['Z', 'X'];
printr $a;
// PRINTS
// CZXputer

Changing the second to third character of the string to ZX:

my $a = "Computer";
$a[1:3] = "ZX";
printr $a;
// PRINTS
// CZXputer

We can also use Code Blocks and Function References:

my $a = "QuickSilver";
$a[:] = @(UC($a));
printr $a;
// PRINTS
// QUICKSILVER

my $a = "QuickSilver";
$a[:] = {{ return UC($a); }};
printr $a;
// PRINTS
// QUICKSILVER

my $a = "QuickSilver";
$a[1:3] = @(UC($a));
printr $a;
// PRINTS
// QUIckSilver

my $a = "QuickSilver";
$a[1:3] = {{ return UC($a); }};
printr $a;
// PRINTS
// QUIckSilver

Sputnik's slicing assignments extend their versatility to string manipulation, offering concise ways to transform substrings efficiently. This functionality is particularly evident when changing entire strings or modifying specific character ranges within a string. Whether replacing characters with constant values or assigning entire substrings, Sputnik's slicing capabilities bring a heightened level of expressiveness to string manipulations, simplifying tasks that would traditionally involve intricate string-handling logic.


Binary Examples

Changing all values in the binary to 5:

my $a = bin(10, 20, 30, 40, 50);
$a[:] = 5;
BinaryExpandPrintLn($a, false);
// PRINTS
// 05 05 05 05 05 -- -- -- -- -- -- -- -- -- -- -- .....

Changing values from [1] to [2] in the binary to 22 and 33 respectively:

my $a = bin(10, 20, 30, 40, 50);
$a[1:3] = [22, 33];
BinaryExpandPrintLn($a, false);
// PRINTS
// 0A 16 21 28 32 -- -- -- -- -- -- -- -- -- -- -- ..!(2

Changing values from [1] to [2] in the binary to 22 and 33 respectively:

my $a = bin(10, 20, 30, 40, 50);
$a[1:3] = bin(22, 33);
BinaryExpandPrintLn($a, false);
// PRINTS
// 0A 16 21 28 32 -- -- -- -- -- -- -- -- -- -- -- ..!(2

Of course Code Blocks and Function References can be used:

my $a = bin(1, 2, 3, 4, 5);
$a[:] = {{ return $a + 1; }};
BinaryExpandPrintLn($a, false);
// PRINTS
// 02 03 04 05 06 -- -- -- -- -- -- -- -- -- -- -- .....

my $a = bin(1, 2, 3, 4, 5);
$a[1:3] = {{ return $a + 1; }};
BinaryExpandPrintLn($a, false);
// PRINTS
// 01 03 04 04 05 -- -- -- -- -- -- -- -- -- -- -- .....


my $a = bin(1, 2, 3, 4, 5);
$a[:] += {{ return $a + 1; }};
BinaryExpandPrintLn($a, false);
// PRINTS
// 03 05 07 09 0B -- -- -- -- -- -- -- -- -- -- -- .....

my $a = bin(1, 2, 3, 4, 5);
$a[1:3] *= {{ return $a + 1; }};
BinaryExpandPrintLn($a, false);
// PRINTS
// 01 06 0C 04 05 -- -- -- -- -- -- -- -- -- -- -- .....

In binary manipulations, Sputnik's slicing assignments introduce a dynamic approach to altering binary values efficiently. The ability to replace all values or specific ranges within a binary with constant values adds a layer of flexibility to binary transformations. Moreover, the integration of code blocks and function references allows for intricate and customizable manipulations. This extends beyond simple value assignments, enabling users to apply complex operations or algorithms to binary elements effortlessly. Whether adjusting individual elements or entire binary sequences, Sputnik's slicing capabilities provide a powerful means for streamlined binary manipulation tasks.


Class Examples

In addition, classes can override the behavior of the [] splice assignment by implementing the __SliceAssign Magic Function. This method takes in the type of slice operation being performed (none, to, from, from-to, from-to-step, from-step, reverse, or clone), the starting offset, the ending index, and the step value and data value being assigned. The class can then use this information to manipulate the underlying data and return the spliced data or a new instance of the class.

Here's an example implementation of a class that overrides the __SliceAssign:

Class Slicer
{
    my $arr;
    Function __Construct($array)
    {
        $arr = $array;
    }
    Function __SliceAssign($type, $offset, $end, $step, $data)
    {
        say "Slice offset $offset end $end step $step";
        say "Slice Data $data";
        switch ($type)
        {
            case @SliceTypeNone:
                say "Type None";
                break;
            case @SliceTypeTo:
                say "Type To";
                break;
            case @SliceTypeFrom:
                say "Type From";
                break;
            case @SliceTypeFromTo:
                say "Type FromTo";
                break;
            case @SliceTypeFromToStep:
                say "Type FromToStep";
                break;
            case @SliceTypeFromStep:
                say "Type FromStep";
                break;
            case @SliceTypeReverse:
                say "Type Reverse";
                break;
            case @SliceTypeColumnTo:
                say "Type Column To";
                break;
            case @SliceTypeColumnFrom:
                say "Type Column From";
                break;
            case @SliceTypeColumnFromTo:
                say "Type Column FromTo";
                break;
            case @SliceTypeColumnFromToStep:
                say "Type Column FromToStep";
                break;
            case @SliceTypeColumnFromStep:
                say "Type Column FromStep";
                break;
            case @SliceTypeColumnReverse:
                say "Type Column Reverse";
                break;
            case @SliceTypeClone:
                say "Type Clone";
                break;
        }
        return array(); // splied array can be returned or new class instance
    }
}

$a = new Slicer(["A" rr "F"]);
$a[:] = 777;
$a[::-1] = 777;
$a[3::-1]= 777;
$a[4:5]= 777;
$a[4:5:7]= 777;
$a[:8]= 777;
$a[9:]= 777;
// PRINTS
// Slice offset 0 end 0 step 0
// Slice Data 777
// Type Clone
// Slice offset -1 end 0 step -1
// Slice Data 777
// Type Reverse
// Slice offset 3 end 0 step -1
// Slice Data 777
// Type FromStep
// Slice offset 4 end 5 step 1
// Slice Data 777
// Type FromTo
// Slice offset 4 end 5 step 7
// Slice Data 777
// Type FromToStep
// Slice offset 0 end 8 step 1
// Slice Data 777
// Type To
// Slice offset 9 end 0 step 1
// Slice Data 777
// Type From

In Sputnik, classes can extend their functionality by overriding the __SliceAssign magic function. This method allows classes to intercept and customize various types of slice assignments, such as none, to, from, from-to, from-to-step, from-step, reverse, or clone. The overridden method receives information about the slice operation, including the type, offset, end index, step value, and the data being assigned. Here, we present an example implementation of a class called Slicer, showcasing how it can manipulate and respond to different slice types. The class handles assignments ranging from cloning to reversing, providing a powerful mechanism for tailored slice behaviors. This flexibility enhances the adaptability of classes in Sputnik, enabling developers to create custom behaviors based on specific slicing operations.


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