Object is the base type of all Crystal objects.
Multiple macros are available to easily declare, initialize and expose instance variables as well as class variables on an Object by generating simple accessor methods.
For example writing:
class Person getter name end
Is the same as writing:
class Person
def name
@name
end
end Similarly, we can write class_getter name to define a class variable, which generates a def self.name class method returning @@name.
We can define as many variables as necessary in a single call. For example getter name, age, city will create a getter method for each of name, age and city.
Instead of plain arguments, we can specify a type as well as an initial value. If the initial value is simple enough Crystal should be able to infer the type of the instance or class variable!
Specifying a type will also declare the instance or class variable with said type and type the accessor method arguments and return type accordingly.
For example writing:
class Person getter name : String getter age = 0 getter city : String = "unspecified" end
Is the same as writing:
class Person
@name : String
@age = 0
@city : String = "unspecified"
def name : String
@name
end
def age
@age
end
def city : String
@city
end
end The initial value of an instance variable is automatically set when the object is constructed. The initial value of a class variable will be set when the program starts up.
Instead of eagerly initializing the value, we can lazily initialize it the first time the accessor method is called.
Since the variable will be lazily initialized the type of the variable will be a nilable type. The generated method however will return the specified type only (not a nilable).
For example writing:
class Person
getter(city : City) { City.unspecified }
end Is equivalent to writing:
class Person
@city : City?
def city : City
if (city = @city).nil?
@city = City.unspecified
else
city
end
end
end Please refer to the different variants to understand how they differ from the general overview presented above:
The setter and class_setter macros are the write counterparts of the getter macros. They declare name=(value) accessor methods. The arguments behave just as for the getter macros. Each setter can have a type as well as an initial value. There is no lazy initialization however since the macro doesn't generate a getter method.
For example writing:
class Person setter name setter age = 0 setter city : String = "unspecified" end
Is the same as writing:
class Person @age = 0 @city : String = "unspecified" def name=(@name) end def age=(@age) end def city=(@city : String) : String end end
For class variables we'd have called class_setter name that would have generated a def self.name=(@@name) class method instead.
The property macros define both getter and setter methods at once.
For example writing:
class Person property name end
Is equivalent to writing:
class Person getter name setter name end
Which is the same as writing:
class Person
def name
@name
end
def name=(@name)
end
end Refer to Getters and Setters above for details. The macros take the exact same arguments.
Deserializes the given JSON in string_or_io into an instance of self, assuming the JSON consists of an JSON object with key root, and whose value is the value to deserialize.
Deserializes the given JSON in string_or_io into an instance of self.
Deserializes the given YAML in string_or_io into an instance of self.
Defines getter methods to access class variables.
Similar to class_getter but defines both raise-on-nil methods as well as query methods that return a nilable value.
Identical to class_getter but defines query methods.
Generates both class_getter and class_setter methods to access instance variables.
Generates both class_getter! and class_setter methods to access instance variables.
Generates both class_getter? and class_setter methods to access instance variables.
Generates setter methods to set class variables.
Defines a clone method that returns a copy of this object with all instance variables cloned (clone is in turn invoked on them).
Defines an #== method by comparing the given fields.
Defines a #hash(hasher) that will append a hash value for the given fields.
Delegate methods to to.
Forwards missing methods to delegate.
Defines getter methods to access instance variables.
Similar to getter but defines both raise-on-nil methods as well as query methods that return a nilable value.
Identical to getter but defines query methods.
Generates setter methods to set instance variables.
Returns the boolean negation of self.
Returns true if this object is not equal to other.
Shortcut to !(self =~ other).
Returns true if this object is equal to other.
Case equality.
Pattern match.
Returns self.
Returns self or nil if can't be restricted to type.
Returns the runtime Class of an object.
Returns a shallow copy (“duplicate”) of this object.
Appends this object's value to hasher, and returns the modified hasher.
Generates an UInt64 hash value for this object.
Returns true if self is included in the collection argument.
Returns true if self is included in the collection argument.
Prints to io an unambiguous and information-rich string representation of this object, typically intended for developers.
Returns an unambiguous and information-rich string representation of this object, typically intended for developers.
Returns true if self inherits or includes type.
Returns self.
Returns true if self is Nil.
Returns self.
Returns self.
Returns a pretty printed version of self.
Pretty prints self into the given printer.
Returns true if method name can be called on self.
Yields self to the block, and then returns self.
Prints a nicely readable and concise string representation of this object, typically intended for users, to io.
Returns a nicely readable and concise string representation of this object, typically intended for users.
Yields self.
Unsafely reinterprets the bytes of an object as being of another type.
Spec::ObjectExtensions
Colorize::ObjectExtensions
Deserializes the given JSON in string_or_io into an instance of self, assuming the JSON consists of an JSON object with key root, and whose value is the value to deserialize.
Int32.from_json(%({"main": 1}), root: "main") # => 1 Deserializes the given JSON in string_or_io into an instance of self. This simply creates a parser = JSON::PullParser and invokes new(parser): classes that want to provide JSON deserialization must provide an def initialize(parser : JSON::PullParser) method.
Int32.from_json("1") # => 1
Array(Int32).from_json("[1, 2, 3]") # => [1, 2, 3] Deserializes the given YAML in string_or_io into an instance of self. This simply creates an instance of YAML::ParseContext and invokes new(parser, yaml): classes that want to provide YAML deserialization must provide an def initialize(parser : YAML::ParseContext, yaml : string_or_io) method.
Hash(String, String).from_yaml("{env: production}") # => {"env" => "production"} Defines getter methods to access class variables.
For example, writing:
class Robot class_getter backend end
Is equivalent to writing:
class Robot
def self.backend
@@backend
end
end Refer to Getters for details.
Similar to class_getter but defines both raise-on-nil methods as well as query methods that return a nilable value.
If a type is specified, then it will become a nilable type (union of the type and Nil). Unlike with class_getter the value is always initialized to nil. There are no initial value or lazy initialization.
For example, writing:
class Robot class_getter! backend : String end
Is equivalent to writing:
class Robot
@@backend : String?
def self.backend? : String?
@@backend
end
def backend : String
@@backend.not_nil!("Robot.backend cannot be nil")
end
end Refer to Getters for general details.
Identical to class_getter but defines query methods.
For example, writing:
class Robot class_getter? backend end
Is equivalent to writing:
class Robot
def self.backend?
@@backend
end
end Refer to Getters for general details.
Generates both class_getter and class_setter methods to access instance variables.
Refer to the aforementioned macros for details.
Generates both class_getter! and class_setter methods to access instance variables.
Refer to the aforementioned macros for details.
Generates both class_getter? and class_setter methods to access instance variables.
Refer to the aforementioned macros for details.
Generates setter methods to set class variables.
For example, writing:
class Robot class_setter factories end
Is equivalent to writing:
class Robot @@factories def self.factories=(@@factories) end end
Refer to Setters for general details.
Defines a clone method that returns a copy of this object with all instance variables cloned (clone is in turn invoked on them).
Defines an #== method by comparing the given fields.
The generated #== method has a self restriction. For classes it will first compare by reference and return true when an object instance is compared with itself, without comparing any of the fields.
class Person def initialize(@name, @age) end # Define a `==` method that compares @name and @age def_equals @name, @age end
Defines a #hash(hasher) that will append a hash value for the given fields.
class Person def initialize(@name, @age) end # Define a hash(hasher) method based on @name and @age def_hash @name, @age end
Delegate methods to to.
Note that due to current language limitations this is only useful when no captured blocks are involved.
class StringWrapper def initialize(@string : String) end delegate downcase, to: @string delegate gsub, to: @string delegate empty?, capitalize, to: @string delegate :[], to: @string end wrapper = StringWrapper.new "HELLO" wrapper.downcase # => "hello" wrapper.gsub(/E/, "A") # => "HALLO" wrapper.empty? # => false wrapper.capitalize # => "Hello"
Forwards missing methods to delegate.
class StringWrapper def initialize(@string : String) end forward_missing_to @string end wrapper = StringWrapper.new "HELLO" wrapper.downcase # => "hello" wrapper.gsub(/E/, "A") # => "HALLO"
Defines getter methods to access instance variables.
Refer to Getters for details.
Similar to getter but defines both raise-on-nil methods as well as query methods that return a nilable value.
If a type is specified, then it will become a nilable type (union of the type and Nil). Unlike the other getter methods the value is always initialized to nil. There are no initial value or lazy initialization.
For example, writing:
class Robot getter! name : String end
Is equivalent to writing:
class Robot
@name : String?
def name? : String?
@name
end
def name : String
@name.not_nil!("Robot#name cannot be nil")
end
end Refer to Getters for general details.
Generates setter methods to set instance variables.
Refer to Setters for general details.
Returns the boolean negation of self.
!true # => false !false # => true !nil # => true !1 # => false !"foo" # => false
This method is a unary operator and usually written in prefix notation (!foo) but it can also be written as a regular method call (foo.!).
NOTE This is a pseudo-method provided directly by the Crystal compiler. It cannot be redefined nor overridden.
Returns true if this object is not equal to other.
By default this method is implemented as !(self == other) so there's no need to override this unless there's a more efficient way to do it.
Shortcut to !(self =~ other).
Returns true if this object is equal to other.
Subclasses override this method to provide class-specific meaning.
Case equality.
The #=== method is used in a case ... when ... end expression.
For example, this code:
case value when x # something when x when y # something when y end
Is equivalent to this code:
if x === value # something when x elsif y === value # something when y end
Object simply implements #=== by invoking #==, but subclasses (notably Regex) can override it to provide meaningful case-equality semantics.
Returns self.
The type of this expression is restricted to type by the compiler. type must be a constant or typeof() expression. It cannot be evaluated at runtime.
If type is not a valid restriction for the expression type, it is a compile-time error. If type is a valid restriction for the expression, but self can't be restricted to type, it raises at runtime. type may be a wider restriction than the expression type, the resulting type is narrowed to the minimal restriction.
a = [1, "foo"][0] typeof(a) # => Int32 | String typeof(a.as(Int32)) # => Int32 a.as(Int32) # => 1 typeof(a.as(Bool)) # Compile Error: can't cast (Int32 | String) to Bool typeof(a.as(String)) # => String a.as(String) # Runtime Error: Cast from Int32 to String failed typeof(a.as(Int32 | Bool)) # => Int32 a.as(Int32 | Bool) # => 1
as in the language specification.NOTE This is a pseudo-method provided directly by the Crystal compiler. It cannot be redefined nor overridden.
Returns self or nil if can't be restricted to type.
The type of this expression is restricted to type by the compiler. If type is not a valid type restriction for the expression type, then it is restricted to Nil. type must be a constant or typeof() expression. It cannot be evaluated at runtime.
a = [1, "foo"][0] typeof(a) # => Int32 | String typeof(a.as?(Int32)) # => Int32 | Nil a.as?(Int32) # => 1 typeof(a.as?(Bool)) # => Bool | Nil a.as?(Bool) # => nil typeof(a.as?(String)) # => String | Nil a.as?(String) # nil typeof(a.as?(Int32 | Bool)) # => Int32 | Nil a.as?(Int32 | Bool) # => 1
#as? in the language specification.NOTE This is a pseudo-method provided directly by the Crystal compiler. It cannot be redefined nor overridden.
Returns the runtime Class of an object.
1.class # => Int32 "hello".class # => String
Compare it with typeof, which returns the compile-time type of an object:
random_value = rand # => 0.627423 value = random_value < 0.5 ? 1 : "hello" value # => "hello" value.class # => String typeof(value) # => Int32 | String
Returns a shallow copy (“duplicate”) of this object.
In order to create a new object with the same value as an existing one, there are two possible routes:
#dup): Constructs a new object with all its properties' values identical to the original object's properties. They are shared references. That means for mutable values that changes to either object's values will be present in both's.#clone): Constructs a new object with all its properties' values being recursive deep copies of the original object's properties. There is no shared state and the new object is a completely independent copy, including everything inside it. This may not be available for every type.A shallow copy is only one level deep whereas a deep copy copies everything below.
This distinction is only relevant for compound values. Primitive types do not have any properties that could be shared or cloned. In that case, #dup and clone are exactly the same.
The #clone method can't be defined on Object. It's not generically available for every type because cycles could be involved, and the clone logic might not need to clone everything.
Many types in the standard library, like Array, Hash, Set and Deque, and all primitive types, define #dup and clone.
Example:
original = {"foo" => [1, 2, 3]}
shallow_copy = original.dup
deep_copy = original.clone
# "foo" references the same array object for both original and shallow copy,
# but not for a deep copy:
original["foo"] << 4
shallow_copy["foo"] # => [1, 2, 3, 4]
deep_copy["foo"] # => [1, 2, 3]
# Assigning new value does not share it to either copy:
original["foo"] = [1]
shallow_copy["foo"] # => [1, 2, 3, 4]
deep_copy["foo"] # => [1, 2, 3] Appends this object's value to hasher, and returns the modified hasher.
Usually the macro def_hash can be used to generate this method. Otherwise, invoke #hash(hasher) on each object's instance variables to accumulate the result:
def hash(hasher) hasher = @some_ivar.hash(hasher) hasher = @some_other_ivar.hash(hasher) hasher end
Generates an UInt64 hash value for this object.
This method must have the property that a == b implies a.hash == b.hash.
The hash value is used along with #== by the Hash class to determine if two objects reference the same hash key.
Subclasses must not override this method. Instead, they must define #hash(hasher), though usually the macro def_hash can be used to generate this method.
Returns true if self is included in the collection argument.
10.in?(0..100) # => true
10.in?({0, 1, 10}) # => true
10.in?(0, 1, 10) # => true
10.in?(:foo, :bar) # => false Returns true if self is included in the collection argument.
10.in?(0..100) # => true
10.in?({0, 1, 10}) # => true
10.in?(0, 1, 10) # => true
10.in?(:foo, :bar) # => false Prints to io an unambiguous and information-rich string representation of this object, typically intended for developers.
It is similar to #to_s(IO), but often provides more information. Ideally, it should contain sufficient information to be able to recreate an object with the same value (given an identical environment).
For types that don't provide a custom implementation of this method, default implementation delegates to #to_s(IO). This said, it is advisable to have an appropriate #inspect implementation on every type. Default implementations are provided by Struct#inspect and Reference#inspect.
::p and ::p! use this method to print an object in STDOUT.
Returns an unambiguous and information-rich string representation of this object, typically intended for developers.
This method should usually not be overridden. It delegates to #inspect(IO) which can be overridden for custom implementations.
Also see #to_s.
Returns true if self inherits or includes type. type must be a constant or typeof()expression. It cannot be evaluated at runtime.
a = 1 a.class # => Int32 a.is_a?(Int32) # => true a.is_a?(String) # => false a.is_a?(Number) # => true a.is_a?(Int32 | String) # => true
is_a? in the language specification.NOTE This is a pseudo-method provided directly by the Crystal compiler. It cannot be redefined nor overridden.
Returns self.
str = "hello" str.itself.object_id == str.object_id # => true
Returns true if self is Nil.
1.nil? # => false nil.nil? # => true
This method is equivalent to #is_a?(Nil).
nil? in the language specification.NOTE This is a pseudo-method provided directly by the Crystal compiler. It cannot be redefined nor overridden.
Returns self.
Nil overrides this method and raises NilAssertionError, see Nil#not_nil!.
This method can be used to remove Nil from a union type. However, it should be avoided if possible and is often considered a code smell. Usually, you can write code in a way that the compiler can safely exclude Nil types, for example using if var. #not_nil! is only meant as a last resort when there's no other way to explain this to the compiler. Either way, consider instead raising a concrete exception with a descriptive message.
message has no effect. It is only used by Nil#not_nil!(message = nil).
Returns self.
Nil overrides this method and raises NilAssertionError, see Nil#not_nil!.
This method can be used to remove Nil from a union type. However, it should be avoided if possible and is often considered a code smell. Usually, you can write code in a way that the compiler can safely exclude Nil types, for example using if var. #not_nil! is only meant as a last resort when there's no other way to explain this to the compiler. Either way, consider instead raising a concrete exception with a descriptive message.
Returns a pretty printed version of self.
Pretty prints self into the given printer.
By default appends a text that is the result of invoking #inspect on self. Subclasses should override for custom pretty printing.
Returns true if method name can be called on self.
name must be a symbol literal, it cannot be evaluated at runtime.
a = 1 a.responds_to?(:abs) # => true a.responds_to?(:size) # => false
#responds_to? in the language specification.NOTE This is a pseudo-method provided directly by the Crystal compiler. It cannot be redefined nor overridden.
Yields self to the block, and then returns self.
The primary purpose of this method is to "tap into" a method chain, in order to perform operations on intermediate results within the chain.
(1..10).tap { |x| puts "original: #{x.inspect}" }
.to_a.tap { |x| puts "array: #{x.inspect}" }
.select { |x| x % 2 == 0 }.tap { |x| puts "evens: #{x.inspect}" }
.map { |x| x*x }.tap { |x| puts "squares: #{x.inspect}" } Prints a nicely readable and concise string representation of this object, typically intended for users, to io.
This method is called when an object is interpolated in a string literal:
"foo #{bar} baz" # calls bar.to_io with the builder for this string IO#<< calls this method to append an object to itself:
io << bar # calls bar.to_s(io)
Thus implementations must not interpolate self in a string literal or call io << self which both would lead to an endless loop.
Also see #inspect(IO).
Yields self. Nil overrides this method and doesn't yield.
This method is useful for dealing with nilable types, to safely perform operations only when the value is not nil.
# First program argument in downcase, or nil ARGV[0]?.try &.downcase
Unsafely reinterprets the bytes of an object as being of another type.
This method is useful to treat a type that is represented as a chunk of bytes as another type where those bytes convey useful information. As an example, you can check the individual bytes of an Int32:
0x01020304.unsafe_as(StaticArray(UInt8, 4)) # => StaticArray[4, 3, 2, 1]
Or treat the bytes of a Float64 as an Int64:
1.234_f64.unsafe_as(Int64) # => 4608236261112822104
This method is unsafe because it behaves unpredictably when the given type doesn't have the same bytesize as the receiver, or when the given type representation doesn't semantically match the underlying bytes.
Also note that because #unsafe_as is a regular method, unlike the pseudo-method #as, you can't specify some types in the type grammar using a short notation, so specifying a static array must always be done as StaticArray(T, N), a tuple as Tuple(...) and so on, never as UInt8[4] or {Int32, Int32}.
© 2012–2026 Manas Technology Solutions.
Licensed under the Apache License, Version 2.0.
https://crystal-lang.org/api/1.19.0/Object.html