=encoding utf8

=head1 NAME

Sidef::Types::Array::Pair

=head1 DESCRIPTION

This class implements a pair data structure, representing an ordered collection of exactly two elements. A Pair is commonly used to represent key-value associations, coordinate points, or any two related values. Pairs are immutable once created and are often used as building blocks for other data structures like hashes.

In Sidef, pairs must be created using the C<Pair()> constructor or the C<Pair.new()> method.

=head1 SYNOPSIS

    # Creating pairs
    var pair1 = Pair('key', 'value')
    var pair2 = Pair('name', 'Alice')
    var pair3 = Pair(10, 20)
    
    # Accessing elements
    say pair1.key      #=> "key"
    say pair1.value    #=> "value"
    say pair1.first    #=> "key"
    say pair1.second   #=> "value"
    
    # Converting pairs
    say pair2.to_a     #=> ["name", "Alice"]
    say pair2.to_h     #=> Hash(name => "Alice")
    
    # Swapping elements
    var swapped = pair3.swap
    say swapped        #=> Pair(20, 10)
    
    # Using pairs in iterations
    var hash = Hash(a => 1, b => 2, c => 3)
    hash.each { |pair|
        say "#{pair.key} => #{pair.value}"
    }

=head1 INHERITS

Inherits methods from:

       * Sidef::Types::Array::Array

=head1 METHODS

=head2 new

    Pair.new(key, value)
    self.new(key, value)

Creates and returns a new Pair object with the specified key and value. This is the primary constructor for creating pairs programmatically.

    var pair = Pair.new('x', 100)
    say pair           #=> Pair(x, 100)
    
    var coords = Pair.new(3.5, 7.2)
    say coords         #=> Pair(3.5, 7.2)

Aliases: I<call>

=cut

=head2 key

    self.key

Returns the first element of the pair, conventionally referred to as the "key". This method provides semantic access to the first component when the pair is used to represent key-value associations.

    var pair = Pair('username', 'john_doe')
    say pair.key       #=> "username"
    
    var point = Pair(10, 20)
    say point.key      #=> 10

Aliases: I<first>

=cut

=head2 value

    self.value

Returns the second element of the pair, conventionally referred to as the "value". This method provides semantic access to the second component when the pair is used to represent key-value associations.

    var pair = Pair('username', 'john_doe')
    say pair.value     #=> "john_doe"
    
    var point = Pair(10, 20)
    say point.value    #=> 20

Aliases: I<second>

=cut

=head2 swap

    self.swap

Swaps the key and value positions in place and returns the modified pair. This mutates the original pair object. This is useful for inverting associations or transforming coordinate systems.

    var original = Pair('name', 'Alice')
    original.swap
    
    say original       #=> Pair(Alice, name)
    
    # Useful for coordinate transformations
    var point = Pair(3, 4)
    point.swap         #=> Pair(4, 3)

=cut

=head2 to_a

    self.to_a

Converts the Pair to a two-element Array containing the key and value in order. This is useful when you need to process the pair as a regular array or pass it to functions expecting array arguments.

    var pair = Pair('color', 'blue')
    var array = pair.to_a
    
    say array          #=> ["color", "blue"]
    say array[0]       #=> "color"
    say array[1]       #=> "blue"
    
    # Useful for destructuring
    var (k, v) = pair.to_a

Aliases: I<to_array>

=cut

=head2 to_h

    self.to_h

Converts the Pair to a Hash containing a single key-value entry. This is convenient when you need to create a hash from a pair or merge a pair into existing hash structures.

    var pair = Pair('age', 25)
    var hash = pair.to_h
    
    say hash           #=> Hash(age => 25)
    say hash{:age}     #=> 25
    
    # Merging multiple pairs
    var settings = [
        Pair('theme', 'dark'),
        Pair('font', 'monospace')
    ].map { .to_h }.reduce { |a, b| a + b }

Aliases: I<to_hash>

=cut

=head2 to_s

    self.to_s

Returns a string representation of the Pair in the format C<Pair(key, value)>. This provides a human-readable serialization of the pair, useful for debugging and display purposes.

    var pair = Pair('status', 'active')
    say pair.to_s      #=> "Pair(status, active)"
    
    var numeric = Pair(42, 3.14)
    say numeric.to_s   #=> "Pair(42, 3.14)"
    
    # Automatically called by say/print
    say pair           #=> Pair(status, active)

Aliases: I<dump>, I<to_str>

=cut

=head1 EXAMPLES

=head2 Working with Hash Entries

    var hash = Hash(
        name   => 'Alice',
        age    => 30,
        city   => 'Boston'
    )
    
    # Iterating as pairs
    hash.each { |pair|
        say "The #{pair.key} is #{pair.value}"
    }
    
    # Filtering pairs
    var adults = hash.grep { |pair|
        pair.key == 'age' && pair.value >= 18
    }

=head2 Coordinate Transformations

    var points = [
        Pair(0, 0),
        Pair(3, 4),
        Pair(5, 12)
    ]
    
    # Swap x and y coordinates
    var reflected = points.map { |p| p.swap }
    
    # Calculate distances from origin
    var distances = points.map { |p|
        hypot(p.key, p.value)
    }

=head2 Building Data Structures

    # Create a hash from an array of pairs
    var pairs = [
        Pair('apple',  1.20),
        Pair('banana', 0.50),
        Pair('cherry', 2.00)
    ]
    
    var prices = Hash(pairs.map{|p| p.to_a}...)
    say prices{:apple}    #=> 1.20
    
    # Invert a hash (swap keys and values)
    var inverted = Hash(
        prices.map { |k, v| Pair(v, k).to_a }...
    )

=head1 SEE ALSO

L<Sidef::Types::Array::Array>, L<Sidef::Types::Hash::Hash>

=head1 AUTHOR

Daniel Șuteu

=cut
