Property definitions

core $ Object :: defaultinit
# The root of the class hierarchy.
#
# Each other class implicitly specializes Object,
# therefore the services of Object are inherited by every other class and are usable
# on each value, including primitive types like integers (`Int`), strings (`String`) and arrays (`Array`).
#
# Note that `nullable Object`, not `Object`, is the root of the type hierarchy
# since the special value `null` is not considered as an instance of Object.
interface Object
	# Type of this instance, automatically specialized in every class
	#
	# A common use case of the virtual type `SELF` is to type an attribute and
	# store another instance of the same type as `self`. It can also be used as as
	# return type to a method producing a copy of `self` or returning an instance
	# expected to be the exact same type as self.
	#
	# This virtual type must be used with caution as it can hinder specialization.
	# In fact, it imposes strict restrictions on all sub-classes and their usage.
	# For example, using `SELF` as a return type of a method `foo`
	# forces all subclasses to ensure that `foo` returns the correct and updated
	# type.
	# A dangerous usage take the form of a method typed by `SELF` which creates
	# and returns a new instance.
	# If not correctly specialized, this method would break when invoked on a
	# sub-class.
	#
	# A general rule for safe usage of `SELF` is to ensure that inputs typed
	# `SELF` are stored in attributes typed `SELF` and returned by methods typed
	# `SELF`, pretty much the same things as you would do with parameter types.
	type SELF: Object

	# An internal hash code for the object based on its identity.
	#
	# Unless specific code, you should not use this method but
	# use `hash` instead.
	#
	# As its name hints it, the internal hash code, is used internally
	# to provide a hash value.
	# It is also used by the `inspect` method to loosely identify objects
	# and helps debugging.
	#
	# ~~~
	# var a = "Hello"
	# var b = a
	# assert a.object_id == b.object_id
	# ~~~
	#
	# The specific details of the internal hash code it let to the specific
	# engine. The rules are the following:
	#
	# * The `object_id` MUST be invariant for the whole life of the object.
	# * Two living instances of the same classes SHOULD NOT share the same `object_id`.
	# * Two instances of different classes MIGHT share the same `object_id`.
	# * The `object_id` of a garbage-collected instance MIGHT be reused by new instances.
	# * The `object_id` of an object MIGHT be non constant across different executions.
	#
	# For instance, the `nitc` compiler uses the address of the object in memory
	# as its `object_id`.
	#
	# TODO rename in something like `internal_hash_code`
	fun object_id: Int is intern

	# Return true if `self` and `other` have the same dynamic type.
	#
	# ~~~
	# assert 1.is_same_type(2)
	# assert "Hello".is_same_type("World")
	# assert not "Hello".is_same_type(2)
	# ~~~
	#
	# The method returns false if the dynamic type of `other` is a subtype of the dynamic type of `self`
	# (or the other way around).
	#
	# Unless specific code, you should not use this method because it is inconsistent
	# with the fact that a subclass can be used in lieu of a superclass.
	fun is_same_type(other: Object): Bool is intern

	# Return true if `self` and `other` are the same instance (i.e. same identity).
	#
	# ~~~
	# var a = new Buffer
	# var b = a
	# var c = new Buffer
	# assert a.is_same_instance(b)
	# assert not a.is_same_instance(c)
	# assert a == c # because both buffers are empty
	# ~~~
	#
	# Obviously, the identity of an object is preserved even if the object is mutated.
	#
	# ~~~
	# var x = [1]
	# var y = x
	# x.add 2
	# assert x.is_same_instance(y)
	# ~~~
	#
	# Unless specific code, you should use `==` instead of `is_same_instance` because
	# most of the time is it the semantic (and user-defined) comparison that make sense.
	#
	# Moreover, relying on `is_same_instance` on objects you do not control
	# might have unexpected effects when libraries reuse objects or intern them.
	fun is_same_instance(other: nullable Object): Bool is intern

	# Have `self` and `other` the same value?
	#
	# ~~~
	# assert 1 + 1 == 2
	# assert not 1 == "1"
	# assert 1.to_s == "1"
	# ~~~
	#
	# The exact meaning of *same value* is left to the subclasses.
	# Implicitly, the default implementation, is `is_same_instance`.
	#
	# The laws of `==` are the following:
	#
	# * reflexivity `a.is_same_instance(b) implies a == b`
	# * symmetry: `(a == b) == (b == a)`
	# * transitivity: `(a == b) and (b == c) implies (a == c)`
	#
	# `==` might not be constant on some objects overtime because of their evolution.
	#
	# ~~~
	# var a = [1]
	# var b = [1]
	# var c = [1,2]
	# assert a == b and not a == c
	# a.add 2
	# assert not a == b and a == c
	# ~~~
	#
	# Lastly, `==` is highly linked with `hash` and a specific redefinition of `==` should
	# usually be associated with a specific redefinition of `hash`.
	#
	# ENSURE `result implies self.hash == other.hash`
	fun ==(other: nullable Object): Bool do return self.is_same_instance(other)

	# Have `self` and `other` different values?
	#
	# `!=` is equivalent with `not ==`.
	fun !=(other: nullable Object): Bool do return not (self == other)

	# Display self on stdout (debug only).
	#
	# This method MUST not be used by programs, it is here for debugging
	# only and can be removed without any notice.
	#
	# TODO: rename to avoid blocking a good identifier like `output`.
	fun output
	do
		'<'.output
		object_id.output
		'>'.output
	end

	# Display class name on stdout (debug only).
	#
	# This method MUST not be used by programs, it is here for debugging
	# only and can be removed without any notice.
	#
	# TODO: rename to avoid blocking a good identifier like `output`.
	fun output_class_name is intern

	# The hash code of the object.
	#
	# The hash code is used in many data-structures and algorithms to identify objects that might be equal.
	# Therefore, the precise semantic of `hash` is highly linked with the semantic of `==`
	# and the only law of `hash` is that `a == b implies a.hash == b.hash`.
	#
	# ~~~
	# assert (1+1).hash == 2.hash
	# assert 1.to_s.hash == "1".hash
	# ~~~
	#
	# `hash` (like `==`) might not be constant on some objects over time because of their evolution.
	#
	# ~~~
	# var a = [1]
	# var b = [1]
	# var c = [1,2]
	# assert a.hash == b.hash
	# a.add 2
	# assert a.hash == c.hash
	# # There is a very high probability that `b.hash != c.hash`
	# ~~~
	#
	# A specific redefinition of `==` should usually be associated with a specific redefinition of `hash`.
	# Note that, unfortunately, a correct definition of `hash` that is lawful with `==` is sometime tricky
	# and a cause of bugs.
	#
	# Without redefinition, `hash` is based on the `object_id` of the instance.
	fun hash: Int do return object_id
end
lib/core/kernel.nit:32,1--225,3