=encoding utf8

=head1 NAME

Sidef::Object::Object - Base class providing the common interface for all Sidef objects.

=head1 DESCRIPTION

This class is the base class for all Sidef objects. It provides fundamental methods for object introspection, cloning, metaprogramming, output, and smart matching, plus the fallback implicit-conversion and comparison protocol that every Sidef object gets for free unless it defines its own.

=head1 SYNOPSIS

    var obj = Object()

=head1 INHERITS

Inherits methods from L<Sidef::Object::Convert>

=head1 CONSTRUCTION

=head2 new

    self.new

Creates and returns a new, empty C<Sidef::Object::Object> instance (an object with no fields). Note that this constructor always blesses into the literal C<Sidef::Object::Object> package itself, regardless of the invocant -- it is not polymorphic. In practice, essentially every built-in Sidef type overrides C<new> with its own constructor; this base implementation only matters for a class that inherits C<new> without providing its own.

=cut

=head2 bless

    obj.bless(ref)

Blesses the raw reference C<ref> into C<obj>'s own class (or, if C<obj> is itself a bare typename, into that class directly) and returns the now-blessed reference. Unlike L</new>, this respects the actual invocant's class.

=cut

=head1 IMPLICIT CONVERSIONS AND COMPARISON

Every Sidef object gets the following fallback behavior for free (via Perl operator overloading), used whenever the language needs to treat an object as a boolean, a number, or a string, or needs to compare/order two objects and the object's own class doesn't define the relevant method itself:

=over 4

=item * B<Boolean context> -- if the object defines a C<to_b> method, that is used; otherwise, the object itself stands in as the boolean value (any object reference is truthy by default).

=item * B<Numeric context> (C<0+>) -- if the object defines C<to_n>, that is used; otherwise, the object itself stands in.

=item * B<String context> (C<"">) -- if the object defines C<to_s>, that is used; otherwise, the object itself stands in.

=item * B<Three-way comparison> (Perl's C<cmp>, used as a fallback ordering) -- if both operands are the same class (or one is a subclass of the other) and that class defines an C<< <=> >> method, that is used. Otherwise, two objects of the exact same class are ordered by their (arbitrary but stable) memory address, and objects of unrelated classes are ordered by comparing their class names as strings. This guarantees any two Sidef objects can be ordered, even if their own types don't otherwise support comparison.

=item * B<Equality> (Perl's C<eq>, used as a fallback for C<==>) -- if both operands are the same class (or one is a subclass of the other) and that class defines an C<==> method, that is used. Otherwise, falls back to the three-way comparison above (equal only if it returns C<0>).

=back

These are internal fallbacks triggered by the language runtime, not methods meant to be called directly by name (there is no C<obj.cmp(...)> or C<obj."0+"()> in Sidef code).

=cut

=head1 OPERATORS

=head2 |>

    a |> b

Pipeline operator. Calls C<b> with C<a> as its first argument and returns the result. If C<b> is an array, its first element is used as the function/method and the rest of its elements are passed as additional arguments after C<a>. If C<b> is a string, it's treated as the name of a method to call on C<a>.

=cut

=head2 &&

    a && b

Logical AND. Returns C<b> if C<a> is truthy, otherwise returns C<a> unchanged. Unlike L</^>, this returns one of the original operand values as-is (Perl-style short-circuit), not a coerced C<Bool>.

=cut

=head2 ||

    a || b

Logical OR. Returns C<a> if C<a> is truthy, otherwise returns C<b>. Like L</&&>, this returns one of the original operand values as-is, not a coerced C<Bool>.

=cut

=head2 ^

    a ^ b

Logical XOR. Returns C<true> if exactly one of C<a> or C<b> is truthy, otherwise returns C<false>. Unlike C<&&> and C<||>, this always returns a proper C<Bool> rather than one of the original operands.

=cut

=head2 \\

    a \\ b

Defined-OR operator. Returns C<b> if C<a> is undefined, otherwise returns C<a> unchanged.

=cut

=head2 :

    a : b

Creates a C<Pair> object from C<a> and C<b>. This is a deprecated alias for the pair operator, using the ASCII colon (U+003A).

=cut

=head2 ：

    a ： b

Creates a C<Pair> object from C<a> and C<b>, using the fullwidth colon (U+FF1A).

=cut

=head2 ⫶

    a ⫶ b

Creates a C<NamedParam> object from C<a> (the name) and C<b> (the value), using the triple colon operator (U+2AF6).

=cut

=head2 smartmatch

    a.smartmatch(b)
    a ~~ b

Performs a context-sensitive comparison between C<a> and C<b>, based on their types. The rules are checked in order, and the first one that applies wins:

=over 4

=item * Both C<a> and C<b> undefined: C<true>.

=item * Both C<a> and C<b> are bare typenames (unblessed strings, not object instances): C<true> only if they are the exact same name (this is a plain string comparison, not a subclass check).

=item * C<a> is an object and C<b> is a typename: C<true> if C<a>'s type is C<b> or a subclass of C<b>.

=item * C<a> is a typename and C<b> is an object: C<true> if C<a> names C<b>'s type or one of its superclasses.

=item * String ~~ RangeString, or RangeString ~~ String: C<true> if the string is contained in the range.

=item * Number ~~ RangeNumber, or RangeNumber ~~ Number: C<true> if the number is contained in the range.

=item * String ~~ String: C<true> if the strings are equal.

=item * Array ~~ Array: C<true> if the arrays are equal.

=item * Array ~~ Regex, or Regex ~~ Array: C<true> if any element of the array matches the regex.

=item * Array ~~ Hash: C<true> if the hash contains every element of the array as a key.

=item * Hash ~~ Array: C<true> if the array contains every key of the hash.

=item * Hash ~~ Hash: C<true> if the hashes are equal.

=item * Hash ~~ Regex, or Regex ~~ Hash: C<true> if any key of the hash matches the regex.

=item * Regex ~~ Regex: C<true> if the regexes are equal.

=item * Any other value ~~ Array, or Array ~~ any other value: C<true> if the array contains that value.

=item * Any other value ~~ Hash, or Hash ~~ any other value: C<true> if the hash has that value as a key.

=item * Any other value ~~ Regex, or Regex ~~ any other value: C<true> if the value matches the regex.

=item * Any value (other than a C<Block>) ~~ Block: calls the block with the value as its argument and returns the (boolean-coerced) result.

=item * If exactly one of C<a>/C<b> is defined and the other isn't: C<false>.

=item * Anything else: falls back to generic equality between C<a> and C<b> (see L</IMPLICIT CONVERSIONS AND COMPARISON>).

=back

Aliases: operator C<~~>

=cut

=head2 ~~

    a ~~ b

Operator form of L</smartmatch>.

Aliases: I<smartmatch>

=cut

=head2 !~

    a !~ b

Returns the negation of L</smartmatch>: C<true> if C<a> does I<not> smart-match C<b>.

=cut

=head1 TYPE INTROSPECTION

=head2 class

    obj.class

Returns the short class name of the object (the part after the last C<::>). For example, an object of class C<Sidef::Types::Number::Number> returns C<"Number">. Also works when called on a bare typename string.

=cut

=head2 ref

    obj.ref

Returns the full class (package) name of the object as a C<String> -- for example, C<"Sidef::Types::Number::Number">. If called on a bare typename string rather than an object instance, returns that typename unchanged.

=cut

=head2 is_a

    self.is_a(class)

Returns C<true> if the object is an instance of C<class>, or of a subclass of C<class>, otherwise C<false>.

Aliases: I<is_an>, I<kind_of>

=cut

=head2 is_object

    self.is_object

Returns C<true> if the value is an instantiated object (a blessed reference), or C<false> if it's a bare typename string.

=cut

=head2 is_typename

    self.is_typename

Returns C<true> if the value is a bare typename string (not an instantiated object), or C<false> if it's an actual object instance. The logical complement of L</is_object>.

=cut

=head2 respond_to

    self.respond_to(method)

Returns C<true> if the object's class has a method with the given name (inherited methods count too), otherwise C<false>.

=cut

=head2 object_type

    self.object_type

Returns a C<String> naming the object's underlying Perl reference type (e.g. C<"HASH">, C<"ARRAY">, C<"SCALAR">).

Aliases: I<reftype>

=cut

=head2 object_id

    self.object_id

Returns a C<Number> representing the memory address of the underlying object reference. Useful for comparing object identity (two variables refer to the same underlying object if their C<object_id> values are equal).

Aliases: I<refaddr>

=cut

=head2 parent_classes

    obj.parent_classes

Returns an C<Array> of all parent classes (superclasses) that the object's class inherits from, recursively walking the C<@ISA> inheritance hierarchy. Each class is only listed once, even if it's reachable through more than one path (e.g. diamond inheritance).

=cut

=head1 CLONING AND SERIALIZATION

=head2 clone

    obj.clone

Returns a shallow copy of the object. For hash-based objects, creates a new hash with the same key-value pairs; for array-based objects, creates a new array with the same elements. For any other underlying reference type (e.g. a scalar-based object), there is nothing to shallow-copy at this level, so the very same reference is returned unchanged.

=cut

=head2 dclone

    self.dclone

Returns a deep copy of the object, recursively cloning nested hash and array structures. Circular references are handled by tracking already-cloned objects (so a cycle is reproduced in the copy rather than causing infinite recursion). Recursion only descends into nested values that are themselves hash- or array-based Sidef objects (i.e. instances of a class that inherits from C<Sidef::Object::Object>); any other kind of value -- including plain Perl data or scalar-based Sidef objects -- is shared as-is between the original and the copy, not cloned.

Aliases: I<deep_clone>

=cut

=head2 dump

    self.dump

Returns a C<String> representation of the object suitable for debugging. For hash-based objects, this includes every key/value pair, in the format C<ClassName(key: value, ...)>; a value that is itself an object with its own C<dump> method is rendered by calling that method recursively, an undefined value is shown as C<nil>, and any other value is stringified directly. For objects whose underlying reference type is not a hash (e.g. array- or scalar-based objects that don't provide their own C<dump>), just the class's type name is returned, with no further detail. If the same object is encountered more than once while dumping (e.g. due to a circular reference), later occurrences are rendered as an abbreviated placeholder instead of being expanded again.

=cut

=head2 to_json

    self.to_json

Converts the object to a JSON string. Internally, this serializes the object's raw underlying value (as returned by C<get_value>), so a custom object will only serialize meaningfully if its underlying value (a hash, array, or scalar) is itself JSON-representable.

    say(Hash("active" => true, "name" => "Sidef", "year" => 2013).to_json)

Output:

    {"name":"Sidef","active":true,"year":2013}

=cut

=head2 interpolate

    self.interpolate(*args)

Joins C<args> into a single string and passes it to C<self>'s own C<new> constructor, returning a new object of C<self>'s class. Used internally to implement string interpolation for classes such as C<String>.

=cut

=head1 METAPROGRAMMING AND LAZY EVALUATION

=head2 lazy

    self.lazy

Wraps the object in a C<Lazy> object, which defers subsequent method calls on it until the result is actually needed.

=cut

=head2 method

    self.method(name, *args)

Returns a C<LazyMethod> object that, when invoked, calls the method named C<name> on C<self> with the given C<args>. Useful for creating a bound method reference to pass around.

=cut

=head2 methods

    self.methods(*args)

Returns a C<Hash> mapping method names to C<LazyMethod> objects (each bound to C<self>, with C<args> pre-filled as its arguments). Names starting with C<_> (private, by convention) or C<(> (internal overload-table entries) are excluded. Importantly, this only inspects methods defined directly in the object's own exact class -- I<inherited> methods (defined only in a parent class) are not included, even though C<self> can still be called with them directly.

=cut

=head2 def_method

    self.def_method(name, block)

Defines a new method called C<name> on the object's class (or, if C<self> is a bare typename, on that class directly). Whenever the method is called, C<block> is invoked with the receiver and all arguments forwarded to it unchanged. Returns C<self>.

=cut

=head2 undef_method

    self.undef_method(name)

Removes the method called C<name> from the object's class. Returns C<self>.

=cut

=head2 alias_method

    self.alias_method(old, new)

Creates C<new> as an alias for the existing method C<old> on the object's class, so both names invoke the same underlying code. Dies if C<old> does not already exist. Returns C<self>.

=cut

=head1 OUTPUT

=head2 say

    self.say

Prints the object to standard output, followed by a newline. Returns C<true> on success, C<false> on failure.

Aliases: I<println>

=cut

=head2 print

    self.print

Prints the object to standard output, without a trailing newline. Returns C<true> on success, C<false> on failure.

=cut

=head1 SEE ALSO

L<Sidef::Object::Convert>

=cut
