Slice(T) - Crystal 1.20.1

# struct Slice(T)

- Slice(T)
- Struct
- Value
- Object

##
Overview

A `Slice` is a `Pointer` with an associated size.

While a pointer is unsafe because no bound checks are performed when reading from and writing to it, reading from and writing to a slice involve bound checks. In this way, a slice is a safe alternative to `Pointer`.

A Slice can be created as read-only: trying to write to it will raise. For example the slice of bytes returned by `String#to_slice` is read-only.

##
Included Modules

- Comparable(Slice(T))
- Indexable::Mutable(T)

##
Defined in:

primitives.cr
slice.cr
slice/sort.cr
yaml/from_yaml.cr
yaml/to_yaml.cr

##
Constructors

- .additive_identity : self

  Returns the additive identity of this type.

- .empty : self

  Creates an empty slice.

- .join(slices : Indexable(Slice)) : Slice

  Returns a new slice that has the elements from slices joined together.

- .new(ctx : YAML::ParseContext, node : YAML::Nodes::Node)
- .new(pointer : Pointer(T), size : Int, *, read_only : Bool = false)

  Creates a slice to the given pointer, bounded by the given size.

- .new(size : Int, value : T, *, read_only = false)

  Allocates `size * sizeof(T)` bytes of heap memory initialized to value and returns a slice pointing to that memory.

- .new(size : Int, *, read_only = false)

  Allocates `size * sizeof(T)` bytes of heap memory initialized to zero and returns a slice pointing to that memory.

- .new(size : Int, *, read_only = false, &)

  Allocates `size * sizeof(T)` bytes of heap memory initialized to the value returned by the block (which is invoked once with each index in the range `0...size`) and returns a slice pointing to that memory.

##
Class Method Summary

- .literal(*args)

  Constructs a read-only `Slice` constant from the given args.

  EXPERIMENTAL Slice literals are still under development. Join the discussion at #2886.

##
Macro Summary

- [](*args, read_only = false)

  Creates a new `Slice` with the given args.

##
Instance Method Summary

- #+(offset : Int) : Slice(T)

  Returns a new slice that is offset elements apart from this slice.

- #+(other : Slice) : Slice

  Returns a new slice that has `self`'s elements followed by other's elements.

- #<=>(other : Slice(U)) forall U

  Combined comparison operator.

- #==(other : Slice(U)) : Bool forall U

  Returns `true` if `self` and other have the same size and all their elements are equal, `false` otherwise.

- #[](start : Int, count : Int) : Slice(T)

  Returns a new slice that starts at start elements from this slice's start, and of exactly count size.

- #[](range : Range) : Slice(T)

  Returns a new slice with the elements in the given range.

- #[]=(index : Int, value : T) : T

  Sets the given value at the given index.

- #[]?(start : Int, count : Int) : Slice(T) | Nil

  Returns a new slice that starts at start elements from this slice's start, and of exactly count size.

- #[]?(range : Range)

  Returns a new slice with the elements in the given range.

- #bytesize : Int32
- #clone

  Returns a deep copy of this slice.

- #copy_from(source : Pointer(T), count) : Nil
- #copy_from(source : self) : Nil

  Copies the contents of source into this slice.

- #copy_to(target : Pointer(T), count) : Nil
- #copy_to(target : self) : Nil

  Copies the contents of this slice into target.

- #dup

  Returns a shallow copy of this slice.

- #fill(value : T, start : Int, count : Int) : self

  Replaces count or less (if there aren't enough) elements starting at the given start index with value.

- #fill(value : T, range : Range) : self

  Replaces the elements within the given range with value.

- #fill(value : T) : self

  Replaces every element in `self` with the given value.

- #fill(start : Int, count : Int, & : Int32 -> T) : self

  Yields each index of `self`, starting at start and for count times (or less if there aren't enough elements), to the given block and then assigns the block's value in that position.

- #fill(range : Range, & : Int32 -> T) : self

  Yields each index of `self`, in the given range, to the given block and then assigns the block's value in that position.

- #fill(*, offset : Int = 0, & : Int32 -> T) : self

  Yields each index of `self` to the given block and then assigns the block's value in that position.

- #hash(hasher)

  See `Object#hash(hasher)`

- #hexdump(io : IO)

  Writes a hexdump of this slice to the given io.

- #hexdump : String

  Returns a hexdump of this slice.

- #hexstring : String

  Returns a hexstring representation of this slice.

- #index(object, offset : Int = 0)

  Returns the index of the first appearance of object in `self` starting from the given offset, or `nil` if object is not in `self`.

- #inspect(io : IO) : Nil

  Appends this struct's name and instance variables names and values to the given IO.

- #map(*, read_only = false, & : T -> _)

  Returns a new slice where elements are mapped by the given block.

- #map!(& : T -> _) : self

  Invokes the given block for each element of `self`, replacing the element with the value returned by the block.

- #map_with_index(offset = 0, *, read_only = false, & : T, Int32 -> _)

  Like `#map`, but the block gets passed both the element and its index.

- #map_with_index!(offset = 0, & : T, Int32 -> _) : self

  Like `#map!`, but the block gets passed both the element and its index.

- #move_from(source : Pointer(T), count) : Nil
- #move_from(source : self) : Nil

  Moves the contents of source into this slice.

- #move_to(target : Pointer(T), count) : Nil
- #move_to(target : self) : Nil

  Moves the contents of this slice into target.

- #pretty_print(pp) : Nil
- #read_only? : Bool

  Returns `true` if this slice cannot be written to.

- #reverse! : self

  Reverses in-place all the elements of `self`.

- #rotate!(n : Int = 1) : self

  Shifts all elements of `self` to the left n times.

- #same?(other : self) : Bool

  Returns `true` if `self` and other point to the same memory, i.e.

- #shuffle!(random : Random | Nil = nil) : self

  Modifies `self` by randomizing the order of elements in the collection.

- #size : Int32

  Returns the size of this slice.

- #sort : self

  Returns a new instance with all elements sorted based on the return value of their comparison method `T#<=>` (see `Comparable#<=>`), using a stable sort algorithm.

- #sort(&block : T, T -> U) : self forall U

  Returns a new instance with all elements sorted based on the comparator in the given block, using a stable sort algorithm.

- #sort! : self

  Sorts all elements in `self` based on the return value of the comparison method `T#<=>` (see `Comparable#<=>`), using a stable sort algorithm.

- #sort!(&block : T, T -> U) : self forall U

  Sorts all elements in `self` based on the comparator in the given block, using a stable sort algorithm.

- #sort_by(&block : T -> _) : self

  Returns a new instance with all elements sorted by the output value of the block.

- #sort_by!(&block : T -> _) : Slice(T)

  Modifies `self` by sorting all elements.

- #swap(index0 : Int, index1 : Int) : self

  Swaps the elements at index0 and index1.

- #to_a

  Returns an `Array` with all the elements in the collection.

- #to_s(io : IO) : Nil

  Same as `#inspect(io)`.

- #to_slice : self
- #to_unsafe : Pointer(T)

  Returns this slice's pointer.

- #to_unsafe_bytes : Bytes

  Returns a new `Bytes` pointing at the same contents as `self`.

- #to_yaml(yaml : YAML::Nodes::Builder) : Nil
- #unsafe_fetch(index : Int) : T

  Returns the element at the given index, without doing any bounds check.

- #unsafe_put(index : Int, value : T)

  Sets the element at the given index to value, without doing any bounds check.

- #unsafe_slice_of(type : U.class) : Slice(U) forall U

  Returns a new `Slice` pointing at the same contents as `self`, but reinterpreted as elements of the given type.

- #unstable_sort : self

  Returns a new instance with all elements sorted based on the return value of their comparison method `T#<=>` (see `Comparable#<=>`), using an unstable sort algorithm.

- #unstable_sort(&block : T, T -> U) : self forall U

  Returns a new instance with all elements sorted based on the comparator in the given block, using an unstable sort algorithm.

- #unstable_sort! : self

  Sorts all elements in `self` based on the return value of the comparison method `T#<=>` (see `Comparable#<=>`), using an unstable sort algorithm..

- #unstable_sort!(&block : T, T -> U) : self forall U

  Sorts all elements in `self` based on the comparator in the given block, using an unstable sort algorithm.

- #unstable_sort_by(&block : T -> _) : self

  Returns a new instance with all elements sorted by the output value of the block.

- #unstable_sort_by!(&block : T -> _) : Slice(T)

  Modifies `self` by sorting all elements.

- #update(index : Int, & : T -> _) : T

  Yields the current element at the given index and updates the value at that index with the block's value.

### Instance methods inherited from module `Comparable(Slice(T))`

<(other : T) : Bool <, <=(other : T) <=, <=>(other : T) <=>, ==(other : T) ==, >(other : T) : Bool >, >=(other : T) >=, clamp(min, max)
clamp(range : Range) clamp

### Instance methods inherited from module `Indexable::Mutable(T)`

[]=(index : Int, value : T) : T []=, fill(value : T, start : Int, count : Int) : self
fill(value : T, range : Range) : self
fill(value : T) : self
fill(start : Int, count : Int, & : Int32 -> T) : self
fill(range : Range, & : Int32 -> T) : self
fill(*, offset : Int = 0, & : Int32 -> T) : self fill, map!(& : T -> _) : self map!, map_with_index!(offset = 0, & : T, Int32 -> _) : self map_with_index!, reverse! : self reverse!, rotate!(n : Int = 1) : self rotate!, shuffle!(random : Random | Nil = nil) : self shuffle!, sort! : self
sort!(&block : T, T -> U) : self forall U sort!, sort_by!(&block : T -> _) : self sort_by!, swap(index0 : Int, index1 : Int) : self swap, unsafe_put(index : Int, value : T) unsafe_put, unstable_sort! : self
unstable_sort!(&block : T, T -> U) : self forall U unstable_sort!, unstable_sort_by!(&block : T -> _) : self unstable_sort_by!, update(index : Int, & : T -> _) : T update

### Instance methods inherited from module `Indexable(T)`

[](index : Int) [], []?(index : Int) []?, bsearch(& : T -> _) bsearch, bsearch_index(& : T, Int32 -> _) bsearch_index, cartesian_product(*others : Indexable) cartesian_product, combinations(size : Int = self.size) combinations, dig(index : Int, *subindexes) dig, dig?(index : Int, *subindexes) dig?, each(& : T -> )
each
each(*, start : Int, count : Int, & : T -> )
each(*, within range : Range, & : T -> ) each, each_cartesian(*others : Indexable, &)
each_cartesian(*others : Indexable) each_cartesian, each_combination(size : Int = self.size, reuse = false, &) : Nil
each_combination(size : Int = self.size, reuse = false) each_combination, each_index(& : Int32 -> ) : Nil
each_index
each_index(*, start : Int, count : Int, &) each_index, each_permutation(size : Int = self.size, reuse = false, &) : Nil
each_permutation(size : Int = self.size, reuse = false) each_permutation, each_repeated_combination(size : Int = self.size, reuse = false, &) : Nil
each_repeated_combination(size : Int = self.size, reuse = false) each_repeated_combination, empty? : Bool empty?, equals?(other : Indexable, &) : Bool
equals?(other, &) equals?, fetch(index : Int, &)
fetch(index, default) fetch, find(if_none, _offset offset : Int, & : T -> )
find(if_none = nil, *, offset : Int, & : T -> ) find, find!(offset : Int = 0, & : T -> ) find!, first(&) first, hash(hasher) hash, index(object, offset : Int = 0)
index(offset : Int = 0, & : T -> ) index, index!(obj, offset : Int = 0)
index!(offset : Int = 0, & : T -> ) index!, join(separator : String | Char | Number = "") : String join, last : T
last(&) last, last? : T | Nil last?, permutations(size : Int = self.size) : Array(Array(T)) permutations, repeated_combinations(size : Int = self.size) : Array(Array(T)) repeated_combinations, reverse_each(& : T -> ) : Nil
reverse_each reverse_each, rindex(value, offset = size - 1)
rindex(offset = size - 1, & : T -> ) rindex, rindex!(value, offset = size - 1)
rindex!(offset = size - 1, & : T -> ) rindex!, sample(n : Int, random : Random | Nil = nil) : Array(T)
sample(random : Random | Nil = nil) sample, size size, to_a(& : T -> U) : Array(U) forall U to_a, unsafe_fetch(index : Int) unsafe_fetch, values_at(*indexes : Int) values_at

### Class methods inherited from module `Indexable(T)`

cartesian_product(indexables : Indexable(Indexable)) cartesian_product, each_cartesian(indexables : Indexable(Indexable), reuse = false, &)
each_cartesian(indexables : Indexable(Indexable), reuse = false) each_cartesian

### Instance methods inherited from module `Enumerable(T)`

accumulate(initial : U) : Array(U) forall U
accumulate : Array(T)
accumulate(initial : U, &block : U, T -> U) : Array(U) forall U
accumulate(&block : T, T -> T) : Array(T) accumulate, all?(& : T -> ) : Bool
all?(pattern) : Bool
all? : Bool all?, any?(& : T -> ) : Bool
any?(pattern) : Bool
any? : Bool any?, chunks(&block : T -> U) forall U chunks, compact_map(& : T -> _) compact_map, count(& : T -> ) : Int32
count(item) : Int32 count, cycle(n, & : T -> ) : Nil
cycle(& : T -> ) : Nil cycle, each(& : T -> ) each, each_cons(count : Int, reuse = false, &) each_cons, each_cons_pair(& : T, T -> ) : Nil each_cons_pair, each_slice(count : Int, reuse = false, &) each_slice, each_step(n : Int, *, offset : Int = 0, & : T -> ) : Nil each_step, each_with_index(offset = 0, &) each_with_index, each_with_object(obj : U, & : T, U -> ) : U forall U each_with_object, empty? : Bool empty?, find(if_none = nil, & : T -> ) find, find!(& : T -> ) : T find!, find_value(if_none = nil, & : T -> ) find_value, first(&)
first(count : Int) : Array(T)
first : T first, first? : T | Nil first?, flat_map(& : T -> _) flat_map, group_by(& : T -> U) forall U group_by, in_groups_of(size : Int, filled_up_with : U = nil) forall U
in_groups_of(size : Int, filled_up_with : U = nil, reuse = false, &) forall U in_groups_of, in_slices_of(size : Int) : Array(Array(T)) in_slices_of, includes?(obj) : Bool includes?, index(& : T -> ) : Int32 | Nil
index(obj) : Int32 | Nil index, index!(& : T -> ) : Int32
index!(obj) : Int32 index!, index_by(& : T -> U) : Hash(U, T) forall U index_by, join(io : IO, separator = "") : Nil
join(separator, io : IO) : Nil
join(separator = "") : String
join(io : IO, separator = "", & : T, IO -> )
join(separator, io : IO, &)
join(separator = "", & : T -> ) join, map(& : T -> U) : Array(U) forall U map, map_with_index(offset = 0, & : T, Int32 -> U) : Array(U) forall U map_with_index, max(count : Int) : Array(T)
max : T max, max? : T | Nil max?, max_by(& : T -> U) : T forall U max_by, max_by?(& : T -> U) : T | Nil forall U max_by?, max_of(& : T -> U) : U forall U max_of, max_of?(& : T -> U) : U | Nil forall U max_of?, min(count : Int) : Array(T)
min : T min, min? : T | Nil min?, min_by(& : T -> U) : T forall U min_by, min_by?(& : T -> U) : T | Nil forall U min_by?, min_of(& : T -> U) : U forall U min_of, min_of?(& : T -> U) : U | Nil forall U min_of?, minmax : Tuple(T, T) minmax, minmax? : Tuple(T | Nil, T | Nil) minmax?, minmax_by(& : T -> U) : Tuple(T, T) forall U minmax_by, minmax_by?(& : T -> U) : Tuple(T, T) | Tuple(Nil, Nil) forall U minmax_by?, minmax_of(& : T -> U) : Tuple(U, U) forall U minmax_of, minmax_of?(& : T -> U) : Tuple(U, U) | Tuple(Nil, Nil) forall U minmax_of?, none?(& : T -> ) : Bool
none?(pattern) : Bool
none? : Bool none?, one?(& : T -> ) : Bool
one?(pattern) : Bool
one? : Bool one?, partition(& : T -> ) : Tuple(Array(T), Array(T))
partition(type : U.class) forall U partition, present? : Bool present?, product(initial : Number)
product
product(initial : Number, & : T -> )
product(& : T -> _) product, reduce(memo, &)
reduce(&) reduce, reduce?(&) reduce?, reject(& : T -> )
reject(type : U.class) forall U
reject(pattern) : Array(T) reject, sample(n : Int, random : Random | Nil = nil) : Array(T)
sample(random : Random | Nil = nil) : T sample, select(& : T -> )
select(type : U.class) : Array(U) forall U
select(pattern) : Array(T) select, size : Int32 size, skip(count : Int) skip, skip_while(& : T -> ) : Array(T) skip_while, sum(initial)
sum
sum(initial, & : T -> )
sum(& : T -> ) sum, take_while(& : T -> ) : Array(T) take_while, tally(hash)
tally : Hash(T, Int32) tally, tally_by(hash, &)
tally_by(&block : T -> U) : Hash(U, Int32) forall U tally_by, to_a : Array(T)
to_a(& : T -> U) : Array(U) forall U to_a, to_h
to_h(& : T -> Tuple(K, V)) forall K, V to_h, to_set : Set(T)
to_set(&block : T -> U) : Set(U) forall U to_set, zip(*others : Indexable | Iterable | Iterator, &)
zip(*others : Indexable | Iterable | Iterator) zip, zip?(*others : Indexable | Iterable | Iterator, &)
zip?(*others : Indexable | Iterable | Iterator) zip?

### Class methods inherited from module `Enumerable(T)`

element_type(x) element_type

### Instance methods inherited from module `Iterable(T)`

chunk(reuse = false, &block : T -> U) forall U chunk, chunk_while(reuse : Bool | Array(T) = false, &block : T, T -> B) forall B chunk_while, cycle(n)
cycle cycle, each each, each_cons(count : Int, reuse = false) each_cons, each_cons_pair each_cons_pair, each_slice(count : Int, reuse = false) each_slice, each_step(n : Int)
each_step(n : Int, *, offset : Int) each_step, each_with_index(offset = 0) each_with_index, each_with_object(obj) each_with_object, slice_after(reuse : Bool | Array(T) = false, &block : T -> B) forall B
slice_after(pattern, reuse : Bool | Array(T) = false) slice_after, slice_before(reuse : Bool | Array(T) = false, &block : T -> B) forall B
slice_before(pattern, reuse : Bool | Array(T) = false) slice_before, slice_when(reuse : Bool | Array(T) = false, &block : T, T -> B) forall B slice_when

### Instance methods inherited from struct `Struct`

==(other : YAML::Any)
==(other) : Bool ==, hash(hasher) hash, inspect(io : IO) : Nil inspect, pretty_print(pp) : Nil pretty_print, to_s(io : IO) : Nil to_s

### Class methods inherited from struct `Struct`

pre_initialize(address : Pointer) : Nil pre_initialize

### Instance methods inherited from struct `Value`

==(other : Log::Metadata::Value)
==(other : JSON::Any)
==(other : YAML::Any)
==(other) ==, dup dup

### Instance methods inherited from class `Object`

! : Bool !, !=(other) !=, !~(other) !~, ==(other) ==, ===(other : JSON::Any)
===(other : YAML::Any)
===(other) ===, =~(other) =~, as(type : Class) as, as?(type : Class) as?, class class, dup dup, hash(hasher)
hash hash, in?(collection : Object) : Bool
in?(*values : Object) : Bool in?, inspect(io : IO) : Nil
inspect : String inspect, is_a?(type : Class) : Bool is_a?, itself itself, nil? : Bool nil?, not_nil!(message)
not_nil! not_nil!, pretty_inspect(width = 79, newline = "\n", indent = 0) : String pretty_inspect, pretty_print(pp : PrettyPrint) : Nil pretty_print, responds_to?(name : Symbol) : Bool responds_to?, tap(&) tap, to_json(io : IO) : Nil
to_json : String to_json, to_pretty_json(indent : String = " ") : String
to_pretty_json(io : IO, indent : String = " ") : Nil to_pretty_json, to_s(io : IO) : Nil
to_s : String to_s, to_yaml(io : IO) : Nil
to_yaml : String to_yaml, try(&) try, unsafe_as(type : T.class) forall T unsafe_as

### Class methods inherited from class `Object`

from_json(string_or_io : String | IO, root : String)
from_json(string_or_io : String | IO) from_json, from_yaml(string_or_io : String | IO) from_yaml

### Macros inherited from class `Object`

class_getter(*names, &block) class_getter, class_getter!(*names) class_getter!, class_getter?(*names, &block) class_getter?, class_property(*names, &block) class_property, class_property!(*names) class_property!, class_property?(*names, &block) class_property?, class_setter(*names) class_setter, def_clone def_clone, def_equals(*fields) def_equals, def_equals_and_hash(*fields) def_equals_and_hash, def_hash(*fields) def_hash, delegate(*methods, to object) delegate, forward_missing_to(delegate) forward_missing_to, getter(*names, &block) getter, getter!(*names) getter!, getter?(*names, &block) getter?, property(*names, &block) property, property!(*names) property!, property?(*names, &block) property?, setter(*names) setter

##
Constructor Detail

def self.additive_identity : self #

Returns the additive identity of this type.

This is an empty slice.

def self.empty : self #

Creates an empty slice.

    slice = Slice(UInt8).empty
    slice.size # => 0

def self.join(slices : Indexable(Slice)) : Slice #

Returns a new slice that has the elements from slices joined together.

    Slice.join([Slice[1, 2], Slice[3, 4, 5]])        # => Slice[1, 2, 3, 4, 5]
    Slice.join({Slice[1], Slice['a'], Slice["xyz"]}) # => Slice[1, 'a', "xyz"]

See also: `#+(other : Slice)`.

def self.new(ctx : YAML::ParseContext, node : YAML::Nodes::Node) #
def self.new(pointer : Pointer(T), size : Int, *, read_only : Bool = false) #

Creates a slice to the given pointer, bounded by the given size. This method does not allocate heap memory.

    ptr = Pointer.malloc(9) { |i| ('a'.ord + i).to_u8 }

    slice = Slice.new(ptr, 3)
    slice.size # => 3
    slice      # => Bytes[97, 98, 99]

    String.new(slice) # => "abc"

def self.new(size : Int, value : T, *, read_only = false) #

Allocates `size * sizeof(T)` bytes of heap memory initialized to value and returns a slice pointing to that memory.

The memory is allocated by the `GC`, so when there are no pointers to this memory, it will be automatically freed.

    slice = Slice.new(3, 10)
    slice # => Slice[10, 10, 10]

def self.new(size : Int, *, read_only = false) #

Allocates `size * sizeof(T)` bytes of heap memory initialized to zero and returns a slice pointing to that memory.

The memory is allocated by the `GC`, so when there are no pointers to this memory, it will be automatically freed.

Only works for primitive integers and floats (`UInt8`, `Int32`, `Float64`, etc.)

    slice = Slice(UInt8).new(3)
    slice # => Bytes[0, 0, 0]

def self.new(size : Int, *, read_only = false, &) #

Allocates `size * sizeof(T)` bytes of heap memory initialized to the value returned by the block (which is invoked once with each index in the range `0...size`) and returns a slice pointing to that memory.

The memory is allocated by the `GC`, so when there are no pointers to this memory, it will be automatically freed.

    slice = Slice.new(3) { |i| i + 10 }
    slice # => Slice[10, 11, 12]

##
Class Method Detail

def self.literal(*args) #

Constructs a read-only `Slice` constant from the given args. The slice contents are stored in the program's read-only data section.

If `T` is specified, it must be one of the `Number::Primitive` types and cannot be a union. The args must all be number literals that fit into `T`'s range, as if they are autocasted into `T`.

If `T` is not specified, it is inferred from args, which must all be number literals of the same type, and cannot be empty.

    x = Slice(UInt8).literal(0, 1, 4, 9, 16, 25)
    x            # => Slice[0, 1, 4, 9, 16, 25]
    x.read_only? # => true

    Slice.literal(1_u8, 2_u8, 3_u8) # => Bytes[1, 2, 3]

EXPERIMENTAL Slice literals are still under development. Join the discussion at #2886.

##
Macro Detail

macro [](*args, read_only = false) #

Creates a new `Slice` with the given args. The type of the slice will be the union of the type of the given args.

The slice is allocated on the heap.

    slice = Slice[1, 'a']
    slice[0]    # => 1
    slice[1]    # => 'a'
    slice.class # => Slice(Char | Int32)

If `T` is a `Number` then this is equivalent to `Number.slice` (numbers will be coerced to the type `T`)

- `Number.slice` is a convenient alternative for designating a specific numerical item type.

##
Instance Method Detail

def +(offset : Int) : Slice(T) #

Returns a new slice that is offset elements apart from this slice.

    slice = Slice.new(5) { |i| i + 10 }
    slice # => Slice[10, 11, 12, 13, 14]

    slice2 = slice + 2
    slice2 # => Slice[12, 13, 14]

def +(other : Slice) : Slice #

Returns a new slice that has `self`'s elements followed by other's elements.

    Slice[1, 2] + Slice[3, 4, 5]          # => Slice[1, 2, 3, 4, 5]
    Slice[1, 2, 3] + Slice['a', 'b', 'c'] # => Slice[1, 2, 3, 'a', 'b', 'c']

See also: `Slice.join` to join multiple slices at once without creating intermediate results.

def <=>(other : Slice(U)) forall U #

Combined comparison operator.

Returns a negative number, `0`, or a positive number depending on whether `self` is less than other, equals other.

It compares the elements of both slices in the same position using the `<=>` operator. As soon as one of such comparisons returns a non-zero value, that result is the return value of the comparison.

If all elements are equal, the comparison is based on the size of the arrays.

    Bytes[8] <=> Bytes[1, 2, 3] # => 7
    Bytes[2] <=> Bytes[4, 2, 3] # => -2
    Bytes[1, 2] <=> Bytes[1, 2] # => 0

def ==(other : Slice(U)) : Bool forall U #

Returns `true` if `self` and other have the same size and all their elements are equal, `false` otherwise.

    Bytes[1, 2] == Bytes[1, 2]    # => true
    Bytes[1, 3] == Bytes[1, 2]    # => false
    Bytes[1, 2] == Bytes[1, 2, 3] # => false

def [](start : Int, count : Int) : Slice(T) #

Returns a new slice that starts at start elements from this slice's start, and of exactly count size.

Negative start is added to `#size`, thus it's treated as index counting from the end of the array, `-1` designating the last element.

Raises `ArgumentError` if count is negative. Raises `IndexError` if the new slice falls outside this slice.

    slice = Slice.new(5) { |i| i + 10 }
    slice # => Slice[10, 11, 12, 13, 14]

    slice[1, 3]   # => Slice[11, 12, 13]
    slice[1, 33]  # raises IndexError
    slice[-3, 2]  # => Slice[12, 13]
    slice[-3, 10] # raises IndexError

def [](range : Range) : Slice(T) #

Returns a new slice with the elements in the given range.

The first element in the returned slice is `self[range.begin]` followed by the next elements up to index `range.end` (or `self[range.end - 1]` if the range is exclusive). If there are fewer elements in `self`, the returned slice is shorter than `range.size`.

    a = Slice["a", "b", "c", "d", "e"]
    a[1..3] # => Slice["b", "c", "d"]

Negative indices count backward from the end of the slice (`-1` is the last element). Additionally, an empty slice is returned when the starting index for an element range is at the end of the slice.

Raises `IndexError` if the new slice falls outside this slice.

    slice = Slice.new(5) { |i| i + 10 }
    slice # => Slice[10, 11, 12, 13, 14]

    slice[1..3]  # => Slice[11, 12, 13]
    slice[1..33] # raises IndexError

def []=(index : Int, value : T) : T #

Sets the given value at the given index. Returns value.

Negative indices can be used to start counting from the end of the container. Raises `IndexError` if trying to set an element outside the container's range.

    ary = [1, 2, 3]
    ary[0] = 5
    ary # => [5, 2, 3]

    ary[3] = 5 # raises IndexError

Raises if this slice is read-only.

def []?(start : Int, count : Int) : Slice(T) | Nil #

Returns a new slice that starts at start elements from this slice's start, and of exactly count size.

Negative start is added to `#size`, thus it's treated as index counting from the end of the array, `-1` designating the last element.

Raises `ArgumentError` if count is negative. Returns `nil` if the new slice falls outside this slice.

    slice = Slice.new(5) { |i| i + 10 }
    slice # => Slice[10, 11, 12, 13, 14]

    slice[1, 3]?   # => Slice[11, 12, 13]
    slice[1, 33]?  # => nil
    slice[-3, 2]?  # => Slice[12, 13]
    slice[-3, 10]? # => nil

def []?(range : Range) #

Returns a new slice with the elements in the given range.

Negative indices count backward from the end of the slice (`-1` is the last element). Additionally, an empty slice is returned when the starting index for an element range is at the end of the slice.

Returns `nil` if the new slice falls outside this slice.

    slice = Slice.new(5) { |i| i + 10 }
    slice # => Slice[10, 11, 12, 13, 14]

    slice[1..3]?  # => Slice[11, 12, 13]
    slice[1..33]? # => nil

def bytesize : Int32 #
def clone #

Returns a deep copy of this slice.

This method allocates memory for the slice copy and stores the return values from calling `#clone` on each item.

def copy_from(source : Pointer(T), count) : Nil #
def copy_from(source : self) : Nil #

Copies the contents of source into this slice.

Raises `IndexError` if the destination slice cannot fit the data being transferred.

def copy_to(target : Pointer(T), count) : Nil #
def copy_to(target : self) : Nil #

Copies the contents of this slice into target.

Raises `IndexError` if the destination slice cannot fit the data being transferred e.g. `dest.size < self.size`.

    src = Slice['a', 'a', 'a']
    dst = Slice['b', 'b', 'b', 'b', 'b']
    src.copy_to dst
    dst             # => Slice['a', 'a', 'a', 'b', 'b']
    dst.copy_to src # raises IndexError

def dup #

Returns a shallow copy of this slice.

This method allocates memory for the slice copy and duplicates the values.

def fill(value : T, start : Int, count : Int) : self #

Replaces count or less (if there aren't enough) elements starting at the given start index with value. Returns `self`.

Negative values of start count from the end of the container.

Raises `IndexError` if the start index is out of range.

Raises `ArgumentError` if count is negative.

    array = [1, 2, 3, 4, 5]
    array.fill(9, 2, 2) # => [1, 2, 9, 9, 5]
    array               # => [1, 2, 9, 9, 5]

Raises if this slice is read-only.

def fill(value : T, range : Range) : self #

Replaces the elements within the given range with value. Returns `self`.

Negative indices count backward from the end of the container.

Raises `IndexError` if the starting index is out of range.

    array = [1, 2, 3, 4, 5]
    array.fill(9, 2..3) # => [1, 2, 9, 9, 5]
    array               # => [1, 2, 9, 9, 5]

Raises if this slice is read-only.

def fill(value : T) : self #

Replaces every element in `self` with the given value. Returns `self`.

    array = [1, 2, 3, 4]
    array.fill(2) # => [2, 2, 2, 2]
    array         # => [2, 2, 2, 2]

Raises if this slice is read-only.

def fill(start : Int, count : Int, & : Int32 -> T) : self #

Yields each index of `self`, starting at start and for count times (or less if there aren't enough elements), to the given block and then assigns the block's value in that position. Returns `self`.

Negative values of start count from the end of the container.

Has no effect if count is zero or negative.

Raises `IndexError` if start is outside the array range.

    a = [1, 2, 3, 4, 5, 6]
    a.fill(2, 3) { |i| i * i * i } # => [1, 2, 8, 27, 64, 6]

Raises if this slice is read-only.

def fill(range : Range, & : Int32 -> T) : self #

Yields each index of `self`, in the given range, to the given block and then assigns the block's value in that position. Returns `self`.

Negative indices count backward from the end of the container.

Raises `IndexError` if the starting index is out of range.

    a = [1, 2, 3, 4, 5, 6]
    a.fill(2..4) { |i| i * i * i } # => [1, 2, 8, 27, 64, 6]

Raises if this slice is read-only.

def fill(*, offset : Int = 0, & : Int32 -> T) : self #

Yields each index of `self` to the given block and then assigns the block's value in that position. Returns `self`.

Accepts an optional offset parameter, which tells the block to start counting from there.

    array = [2, 1, 1, 1]
    array.fill { |i| i * i }            # => [0, 1, 4, 9]
    array                               # => [0, 1, 4, 9]
    array.fill(offset: 3) { |i| i * i } # => [9, 16, 25, 36]
    array                               # => [9, 16, 25, 36]

Raises if this slice is read-only.

def hash(hasher) #

See `Object#hash(hasher)`

def hexdump(io : IO) #

Writes a hexdump of this slice to the given io.

`self` must be a `Slice(UInt8)`. To call this method on other `Slice`s, `#to_unsafe_bytes` should be used first.

This method is specially useful for debugging binary data and incoming/outgoing data in protocols.

Returns the number of bytes written to io.

    slice = UInt8.slice(97, 62, 63, 8, 255)
    slice.hexdump(STDOUT)

Prints:

    00000000  61 3e 3f 08 ff                                    a>?..

def hexdump : String #

Returns a hexdump of this slice.

`self` must be a `Slice(UInt8)`. To call this method on other `Slice`s, `#to_unsafe_bytes` should be used first.

This method is specially useful for debugging binary data and incoming/outgoing data in protocols.

    slice = UInt8.slice(97, 62, 63, 8, 255)
    slice.hexdump # => "00000000  61 3e 3f 08 ff                                    a>?..\n"

    # assume little-endian system
    slice = Int16.slice(97, 62, 1000, -2)
    slice.to_unsafe_bytes.hexdump # => "00000000  61 00 3e 00 e8 03 fe ff                           a.>.....\n"

def hexstring : String #

Returns a hexstring representation of this slice.

`self` must be a `Slice(UInt8)`. To call this method on other `Slice`s, `#to_unsafe_bytes` should be used first.

    UInt8.slice(97, 62, 63, 8, 255).hexstring # => "613e3f08ff"

    # assume little-endian system
    Int16.slice(97, 62, 1000, -2).to_unsafe_bytes.hexstring # => "61003e00e803feff"

def index(object, offset : Int = 0) #
Description copied from module Indexable(T)

Returns the index of the first appearance of object in `self` starting from the given offset, or `nil` if object is not in `self`.

    [1, 2, 3, 1, 2, 3].index(2, offset: 2) # => 4

def inspect(io : IO) : Nil #
Description copied from struct Struct

Appends this struct's name and instance variables names and values to the given IO.

    struct Point
      def initialize(@x : Int32, @y : Int32)
      end
    end

    p1 = Point.new 1, 2
    p1.to_s    # "Point(@x=1, @y=2)"
    p1.inspect # "Point(@x=1, @y=2)"

def map(*, read_only = false, & : T -> _) #

Returns a new slice where elements are mapped by the given block.

    slice = Slice[1, 2.5, "a"]
    slice.map &.to_s # => Slice["1", "2.5", "a"]

def map!(& : T -> _) : self #

Invokes the given block for each element of `self`, replacing the element with the value returned by the block. Returns `self`.

    a = [1, 2, 3]
    a.map! { |x| x * x }
    a # => [1, 4, 9]

Raises if this slice is read-only.

def map_with_index(offset = 0, *, read_only = false, & : T, Int32 -> _) #

Like `#map`, but the block gets passed both the element and its index.

Accepts an optional offset parameter, which tells it to start counting from there.

def map_with_index!(offset = 0, & : T, Int32 -> _) : self #

Like `#map!`, but the block gets passed both the element and its index.

Accepts an optional offset parameter, which tells it to start counting from there.

    gems = ["crystal", "pearl", "diamond"]
    gems.map_with_index! { |gem, i| "#{i}: #{gem}" }
    gems # => ["0: crystal", "1: pearl", "2: diamond"]

Raises if this slice is read-only.

def move_from(source : Pointer(T), count) : Nil #
def move_from(source : self) : Nil #

Moves the contents of source into this slice. source and `self` may overlap; the copy is always done in a non-destructive manner.

Raises `IndexError` if the destination slice cannot fit the data being transferred.

def move_to(target : Pointer(T), count) : Nil #
def move_to(target : self) : Nil #

Moves the contents of this slice into target. target and `self` may overlap; the copy is always done in a non-destructive manner.

Raises `IndexError` if the destination slice cannot fit the data being transferred e.g. `dest.size < self.size`.

    src = Slice['a', 'a', 'a']
    dst = Slice['b', 'b', 'b', 'b', 'b']
    src.move_to dst
    dst             # => Slice['a', 'a', 'a', 'b', 'b']
    dst.move_to src # raises IndexError

See also: `Pointer#move_to`.

def pretty_print(pp) : Nil #
def read_only? : Bool #

Returns `true` if this slice cannot be written to.

def reverse! : self #

Reverses in-place all the elements of `self`. Returns `self`.

Raises if this slice is read-only.

def rotate!(n : Int = 1) : self #

Shifts all elements of `self` to the left n times. Returns `self`.

    a1 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    a2 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    a3 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

    a1.rotate!
    a2.rotate!(1)
    a3.rotate!(3)

    a1 # => [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
    a2 # => [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
    a3 # => [3, 4, 5, 6, 7, 8, 9, 0, 1, 2]

Raises if this slice is read-only.

def same?(other : self) : Bool #

Returns `true` if `self` and other point to the same memory, i.e. pointer and size are identical.

    slice = Slice[1, 2, 3]
    slice.same?(slice)           # => true
    slice == Slice[1, 2, 3]      # => false
    slice.same?(slice + 1)       # => false
    (slice + 1).same?(slice + 1) # => true
    slice.same?(slice[0, 2])     # => false

def shuffle!(random : Random | Nil = nil) : self #

Modifies `self` by randomizing the order of elements in the collection. Returns `self`.

    a = [1, 2, 3, 4, 5]
    a.shuffle! # => [3, 5, 2, 4, 1]
    a          # => [3, 5, 2, 4, 1]

Uses the random instance when provided if the randomness needs to be controlled or to follow some traits. For example the following shuffle will always result in the same order:

    a = [1, 2, 3, 4, 5]
    a.shuffle!(Random.new(42)) # => [3, 2, 4, 5, 1]
    a.shuffle!(Random.new(42)) # => [3, 2, 4, 5, 1]
    a                          # => [3, 2, 4, 5, 1]

Raises if this slice is read-only.

def size : Int32 #

Returns the size of this slice.

    Slice(UInt8).new(3).size # => 3

def sort : self #

Returns a new instance with all elements sorted based on the return value of their comparison method `T#<=>` (see `Comparable#<=>`), using a stable sort algorithm.

    a = Slice[3, 1, 2]
    a.sort # => Slice[1, 2, 3]
    a      # => Slice[3, 1, 2]

See `#sort!` for details on the sorting mechanism.

Raises `ArgumentError` if the comparison between any two elements returns `nil`.

def sort(&block : T, T -> U) : self forall U #

Returns a new instance with all elements sorted based on the comparator in the given block, using a stable sort algorithm.

    a = Slice[3, 1, 2]
    b = a.sort { |a, b| b <=> a }

    b # => Slice[3, 2, 1]
    a # => Slice[3, 1, 2]

See `Indexable::Mutable#sort!(&block : T, T -> U)` for details on the sorting mechanism.

Raises `ArgumentError` if for any two elements the block returns `nil`.

def sort! : self #

Sorts all elements in `self` based on the return value of the comparison method `T#<=>` (see `Comparable#<=>`), using a stable sort algorithm.

    slice = Slice[3, 1, 2]
    slice.sort!
    slice # => Slice[1, 2, 3]

This sort operation modifies `self`. See `#sort` for a non-modifying option that allocates a new instance.

The sort mechanism is implemented as merge sort. It is stable, which is typically a good default.

Stability means that two elements which compare equal (i.e. `a <=> b == 0`) keep their original relation. Stable sort guarantees that `[a, b].sort!` always results in `[a, b]` (given they compare equal). With unstable sort, the result could also be `[b, a]`.

If stability is expendable, `#unstable_sort!` provides a performance advantage over stable sort. As an optimization, if `T` is any primitive integer type, `Char`, any enum type, any `Pointer` instance, `Symbol`, or `Time::Span`, then an unstable sort is automatically used.

Raises `ArgumentError` if the comparison between any two elements returns `nil`.

def sort!(&block : T, T -> U) : self forall U #

Sorts all elements in `self` based on the comparator in the given block, using a stable sort algorithm.

    slice = Slice[3, 1, 2]
    # This is a reverse sort (forward sort would be `a <=> b`)
    slice.sort! { |a, b| b <=> a }
    slice # => Slice[3, 2, 1]

The block must implement a comparison between two elements a and b, where `a < b` outputs a negative value, `a == b` outputs `0`, and `a > b` outputs a positive value. The comparison operator (`Comparable#<=>`) can be used for this.

The block's output type must be `<= Int32?`, but returning an actual `nil` value is an error.

This sort operation modifies `self`. See `#sort(&block : T, T -> U)` for a non-modifying option that allocates a new instance.

The sort mechanism is implemented as merge sort. It is stable, which is typically a good default.

Stability means that two elements which compare equal (i.e. `a <=> b == 0`) keep their original relation. Stable sort guarantees that `[a, b].sort!` always results in `[a, b]` (given they compare equal). With unstable sort, the result could also be `[b, a]`.

If stability is expendable, `#unstable_sort!(&block : T, T -> U)` provides a performance advantage over stable sort.

Raises `ArgumentError` if for any two elements the block returns `nil`.

def sort_by(&block : T -> _) : self #

Returns a new instance with all elements sorted by the output value of the block. The output values are compared via the comparison method `T#<=>` (see `Comparable#<=>`), using a stable sort algorithm.

    a = Slice["apple", "pear", "fig"]
    b = a.sort_by { |word| word.size }
    b # => Slice["fig", "pear", "apple"]
    a # => Slice["apple", "pear", "fig"]

If stability is expendable, `#unstable_sort_by(&block : T -> _)` provides a performance advantage over stable sort.

See `Indexable::Mutable#sort_by!(&block : T -> _)` for details on the sorting mechanism.

Raises `ArgumentError` if the comparison between any two comparison values returns `nil`.

def sort_by!(&block : T -> _) : Slice(T) #

Modifies `self` by sorting all elements. The given block is called for each element, then the comparison method `<=>` is called on the object returned from the block to determine sort order.

    a = Slice["apple", "pear", "fig"]
    a.sort_by! { |word| word.size }
    a # => Slice["fig", "pear", "apple"]

def swap(index0 : Int, index1 : Int) : self #

Swaps the elements at index0 and index1. Returns `self`.

Negative indices can be used to start counting from the end of the container. Raises `IndexError` if either index is out of bounds.

    a = ["first", "second", "third"]
    a.swap(1, 2)  # => ["first", "third", "second"]
    a             # => ["first", "third", "second"]
    a.swap(0, -1) # => ["second", "third", "first"]
    a             # => ["second", "third", "first"]
    a.swap(2, 3)  # raises IndexError

Raises if this slice is read-only.

def to_a #
Description copied from module Enumerable(T)

Returns an `Array` with all the elements in the collection.

    (1..5).to_a # => [1, 2, 3, 4, 5]

def to_s(io : IO) : Nil #
Description copied from struct Struct

Same as `#inspect(io)`.

def to_slice : self #
def to_unsafe : Pointer(T) #

Returns this slice's pointer.

    slice = Slice.new(3, 10)
    slice.to_unsafe[0] # => 10

def to_unsafe_bytes : Bytes #

Returns a new `Bytes` pointing at the same contents as `self`.

WARNING This method is unsafe: the returned slice is writable if `self` is also writable, and modifications through the returned slice may violate the binary representations of Crystal objects. Additionally, the same elements may produce different results depending on the system endianness.

    # assume little-endian system
    ints = Slice[0x01020304, 0x05060708]
    bytes = ints.to_unsafe_bytes # => Bytes[0x04, 0x03, 0x02, 0x01, 0x08, 0x07, 0x06, 0x05]
    bytes[2] = 0xAD
    ints # => Slice[0x01AD0304, 0x05060708]

def to_yaml(yaml : YAML::Nodes::Builder) : Nil #
def unsafe_fetch(index : Int) : T #
Description copied from module Indexable(T)

Returns the element at the given index, without doing any bounds check.

`Indexable` makes sure to invoke this method with index in `0...size`, so converting negative indices to positive ones is not needed here.

Clients never invoke this method directly. Instead, they access elements with `#[](index)` and `#[]?(index)`.

This method should only be directly invoked if you are absolutely sure the index is in bounds, to avoid a bounds check for a small boost of performance.

def unsafe_put(index : Int, value : T) #
Description copied from module Indexable::Mutable(T)

Sets the element at the given index to value, without doing any bounds check.

`Indexable::Mutable` makes sure to invoke this method with index in `0...size`, so converting negative indices to positive ones is not needed here.

Clients never invoke this method directly. Instead, they modify elements with `#[]=(index, value)`.

This method should only be directly invoked if you are absolutely sure the index is in bounds, to avoid a bounds check for a small boost of performance.

def unsafe_slice_of(type : U.class) : Slice(U) forall U #

Returns a new `Slice` pointing at the same contents as `self`, but reinterpreted as elements of the given type.

The returned slice never refers to more memory than `self`; if the last bytes of `self` do not fit into a `U`, they are excluded from the returned slice.

WARNING This method is unsafe: elements are reinterpreted using `#unsafe_as`, and the resulting slice may not be properly aligned. Additionally, the same elements may produce different results depending on the system endianness.

    # assume little-endian system
    bytes = Bytes[0x01, 0x02, 0x03, 0x04, 0xFF, 0xFE]
    bytes.unsafe_slice_of(Int8)  # => Slice[1_i8, 2_i8, 3_i8, 4_i8, -1_i8, -2_i8]
    bytes.unsafe_slice_of(Int16) # => Slice[513_i16, 1027_i16, -257_i16]
    bytes.unsafe_slice_of(Int32) # => Slice[0x04030201]

def unstable_sort : self #

Returns a new instance with all elements sorted based on the return value of their comparison method `T#<=>` (see `Comparable#<=>`), using an unstable sort algorithm.

    a = Slice[3, 1, 2]
    a.unstable_sort # => Slice[1, 2, 3]
    a               # => Slice[3, 1, 2]

See `Indexable::Mutable#unstable_sort!` for details on the sorting mechanism.

Raises `ArgumentError` if the comparison between any two elements returns `nil`.

def unstable_sort(&block : T, T -> U) : self forall U #

Returns a new instance with all elements sorted based on the comparator in the given block, using an unstable sort algorithm.

    a = Slice[3, 1, 2]
    b = a.unstable_sort { |a, b| b <=> a }

    b # => Slice[3, 2, 1]
    a # => Slice[3, 1, 2]

See `Indexable::Mutable#unstable_sort!(&block : T, T -> U)` for details on the sorting mechanism.

Raises `ArgumentError` if for any two elements the block returns `nil`.

def unstable_sort! : self #

Sorts all elements in `self` based on the return value of the comparison method `T#<=>` (see `Comparable#<=>`), using an unstable sort algorithm..

    slice = Slice[3, 1, 2]
    slice.unstable_sort!
    slice # => Slice[1, 2, 3]

This sort operation modifies `self`. See `#unstable_sort` for a non-modifying option that allocates a new instance.

The sort mechanism is implemented as introsort. It does not guarantee stability between equally comparing elements. This offers higher performance but may be unexpected in some situations.

Stability means that two elements which compare equal (i.e. `a <=> b == 0`) keep their original relation. Stable sort guarantees that `[a, b].sort!` always results in `[a, b]` (given they compare equal). With unstable sort, the result could also be `[b, a]`.

If stability is necessary, use `#sort!` instead.

Raises `ArgumentError` if the comparison between any two elements returns `nil`.

def unstable_sort!(&block : T, T -> U) : self forall U #

Sorts all elements in `self` based on the comparator in the given block, using an unstable sort algorithm.

    slice = Slice[3, 1, 2]
    # This is a reverse sort (forward sort would be `a <=> b`)
    slice.unstable_sort! { |a, b| b <=> a }
    slice # => Slice[3, 2, 1]

The block must implement a comparison between two elements a and b, where `a < b` outputs a negative value, `a == b` outputs `0`, and `a > b` outputs a positive value. The comparison operator (`Comparable#<=>`) can be used for this.

The block's output type must be `<= Int32?`, but returning an actual `nil` value is an error.

This sort operation modifies `self`. See `#unstable_sort(&block : T, T -> U)` for a non-modifying option that allocates a new instance.

The sort mechanism is implemented as introsort. It does not guarantee stability between equally comparing elements. This offers higher performance but may be unexpected in some situations.

Stability means that two elements which compare equal (i.e. `a <=> b == 0`) keep their original relation. Stable sort guarantees that `[a, b].sort!` always results in `[a, b]` (given they compare equal). With unstable sort, the result could also be `[b, a]`.

If stability is necessary, use `#sort!(&block : T, T -> U)` instead.

Raises `ArgumentError` if for any two elements the block returns `nil`.

def unstable_sort_by(&block : T -> _) : self #

Returns a new instance with all elements sorted by the output value of the block. The output values are compared via the comparison method `#<=>` (see `Comparable#<=>`), using an unstable sort algorithm.

    a = Slice["apple", "pear", "fig"]
    b = a.unstable_sort_by { |word| word.size }
    b # => Slice["fig", "pear", "apple"]
    a # => Slice["apple", "pear", "fig"]

If stability is necessary, use `#sort_by(&block : T -> _)` instead.

See `Indexable::Mutable#unstable_sort!(&block : T -> _)` for details on the sorting mechanism.

Raises `ArgumentError` if the comparison between any two comparison values returns `nil`.

def unstable_sort_by!(&block : T -> _) : Slice(T) #

Modifies `self` by sorting all elements. The given block is called for each element, then the comparison method `<=>` is called on the object returned from the block to determine sort order.

    a = Slice["apple", "pear", "fig"]
    a.sort_by! { |word| word.size }
    a # => Slice["fig", "pear", "apple"]

This method does not guarantee stability between equally sorting elements. Which results in a performance advantage over stable sort.

def update(index : Int, & : T -> _) : T #

Yields the current element at the given index and updates the value at that index with the block's value. Returns the new value.

Raises `IndexError` if trying to set an element outside the container's range.

    array = [1, 2, 3]
    array.update(1) { |x| x * 2 } # => 4
    array                         # => [1, 4, 3]
    array.update(5) { |x| x * 2 } # raises IndexError

Raises if this slice is read-only.