A slicing operation is a simple way to extract a range of elements from a container. The boo compiler supports native slicing operations on lists, arrays and strings. Support for user defined slicing operations is planned but currently not implemented.
General Syntax
A slicing operation is applied to a container through the following sintax:
range = container[<firstIndexWanted> : <firstIndexNotWanted> : <step>]
When firstIndexWanted is omitted it is assumed to be 0.
When firstIndexNotWanted is omitted it is assumed to be equals to len(container)+1.
When step is omitted it is assumed to be 1.
List Slicing
l = [1, 2, 3, 4]
assert [1] == l[0]
assert [1] == l[0:1]
assert [1, 2] == l[0:2]
assert [2, 3] == l[1:3]
assert [1, 2, 3, 4] == l[:]
Array Slicing
a = (1, 2, 3, 4)
assert (1,) == a[0:1]
assert (1, 2, 3) == a[:3]
assert (1, 2) == a[:2]
assert (1, 3) == a[::2]
assert (4, 3) == a[-2:-1:-1]
String Slicing
s = "bamboo"
assert "b" == a[0:1]
assert "boo" == a[3:]
assert "bo" == a[3:-1]
Considerations and differences between slices types
If you read the examples with some attention, you saw that [] is used to create slices of lists - Boo.Lang.List or System.Collections.IList, to be more specific -, and using () you create slices of arrays. Consider the following example:
print([1, 2, 3].GetType()) print((4, 5, 6).GetType()) print(("1", "2", 3).GetType()) print(("a", "b").GetType()) print(["foo", "bar"].GetType())
So, having that in mind, you must specify the desired slice type when using it with methods:
class Test:
def example(itens):
i = 0
itensLen = len(itens)
while i < itensLen:
print (itens[i])
++i
t = Test()
t.example([1, 2, 3, 4, 5])
the above code will result on compile time error The type 'System.Object' does not support splicing'. This is because the boo compiler cannot predict that you want to pass a collection to the method, and since the type Object is neither a collection or array, we got the error. To handle that, explicitly tell the compiler that you will pass a collection to the method:
import System.Collections
class Test:
def example(itens as IList):
i = 0
itensLen = len(itens)
while i < itensLen:
print (itens[i])
++i
t = Test()
t.example([1, 2, 3, 4, 5])
Why cant the "slice type" be inferred as the rest of the types are? I think C++ can do this using template partial specialization. For example
t.example([1, 2, 3, 4, 5])
should generate a template instance which takes an IList for itens in the above (wiki) example
t.example((1, 2, 3, 4, 5))
should generate a template instance which takes Int32[]
I think templates are not supported in boo as of now but adding a C++ template like mechanism will take boo's type inferencing mechanism to new places. IMHO adding such a system should be high on the list of priorities.