abstract class Object
¶
Object
is the base type of all Crystal objects.
Included modules
Colorize::ObjectExtensions
Spec::ObjectExtensions
Direct known subclasses
Reference
Value
Class methods¶
.from_json(string_or_io, root : String)
¶
(string_or_io, root : String)
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
.from_json(string_or_io)
¶
(string_or_io)
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]
.from_yaml(string_or_io : String | IO)
¶
(string_or_io : String | IO)
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"}
Methods¶
#! : Bool
¶
: Bool
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.
#!=(other)
¶
(other)
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.
abstract
#==(other)
¶
(other)
Returns true
if this object is equal to other.
Subclasses override this method to provide class-specific meaning.
#===(other)
¶
(other)
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.
#=~(other)
¶
(other)
Pattern match.
Overridden by descendants (notably Regex
and String
) to provide meaningful
pattern-match semantics.
#as(type : Class)
¶
(type : Class)
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?(type : Class)
¶
(type : Class)
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
#class
¶
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
abstract
#dup
¶
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:
- create a shallow copy (
#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. - create a deep copy (
#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]
abstract
#hash(hasher)
¶
(hasher)
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
#hash
¶
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.
#in?(*values : Object) : Bool
¶
(*values : Object) : Bool
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
#in?(collection) : Bool
¶
(collection) : Bool
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
#inspect : String
¶
: String
Returns a String
representation of this object suitable
to be embedded inside other expressions, sometimes providing
more information about this object.
#inspect
(and #inspect(io)
) are the methods used when
you invoke #to_s
or #inspect
on an object that holds
other objects and wants to show them. For example when you
invoke Array#to_s
, #inspect
will be invoked on each element:
ary = ["one", "two", "three, etc."]
ary.inspect # => ["one", "two", "three, etc."]
Note that if Array invoked #to_s
on each of the elements
above, the output would have been this:
ary = ["one", "two", "three, etc."]
# If inspect invoked to_s on each element...
ary.inspect # => [one, two, three, etc.]
Note that it's not clear how many elements the array has,
or which are they, because #to_s
doesn't guarantee that
the string representation is clearly delimited (in the case
of String
the quotes are not shown).
Also note that sometimes the output of #inspect
will look
like a Crystal expression that will compile, but this isn't
always the case, nor is it necessary. Notably, Reference#inspect
and Struct#inspect
return values that don't compile.
Classes must usually not override this method. Instead,
they must override inspect(io)
, which must append to the
given IO
object.
#inspect(io : IO) : Nil
¶
(io : IO) : Nil
Appends a string representation of this object
to the given IO
object.
Similar to to_s(io)
, but usually appends more information
about this object.
See #inspect
.
#is_a?(type : Class) : Bool
¶
(type : Class) : Bool
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
#nil? : Bool
¶
: Bool
Returns true
if self
is Nil
.
1.nil? # => false
nil.nil? # => true
This method is equivalent to is_a?(Nil)
.
NOTE: This is a pseudo-method provided directly by the Crystal compiler.
It cannot be redefined nor overridden.
#not_nil!
¶
Returns self
.
Nil
overrides this method and raises NilAssertionError
, see Nil#not_nil!
.
#pretty_inspect(width = 79, newline = "\n", indent = 0) : String
¶
(width = 79, newline = "\n", indent = 0) : String
Returns a pretty printed version of self
.
#pretty_print(pp : PrettyPrint) : Nil
¶
(pp : PrettyPrint) : Nil
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.
#responds_to?(name : Symbol) : Bool
¶
(name : Symbol) : Bool
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
#tap
¶
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}" }
#to_s : String
¶
: String
Returns a string representation of this object.
Descendants must usually not override this method. Instead,
they must override to_s(io)
, which must append to the given
IO object.
abstract
#to_s(io : IO) : Nil
¶
(io : IO) : Nil
Appends a String
representation of this object
to the given IO
object.
An object must never append itself to the io argument,
as this will in turn call to_s(io)
on it.
#try
¶
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
#unsafe_as(type : T.class) forall T
¶
(type : T.class) forall T
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}
.
Macros¶
class_getter
¶
Defines getter methods for each of the given arguments.
Writing:
class Person
class_getter name
end
Is the same as writing:
class Person
def self.name
@@name
end
end
The arguments can be string literals, symbol literals or plain names:
class Person
class_getter :name, "age"
end
If a type declaration is given, a variable with that name is declared with that type.
class Person
class_getter name : String
end
Is the same as writing:
class Person
@@name : String
def self.name : String
@@name
end
end
The type declaration can also include an initial value:
class Person
class_getter name : String = "John Doe"
end
Is the same as writing:
class Person
@@name : String = "John Doe"
def self.name : String
@@name
end
end
An assignment can be passed too, but in this case the type of the variable must be easily inferable from the initial value:
class Person
class_getter name = "John Doe"
end
Is the same as writing:
class Person
@@name = "John Doe"
def self.name : String
@@name
end
end
If a block is given to the macro, a getter is generated with a variable that is lazily initialized with the block's contents:
class Person
class_getter(birth_date) { Time.local }
end
Is the same as writing:
class Person
def self.birth_date
if (value = @@birth_date).nil?
@@birth_date = Time.local
else
value
end
end
end
class_getter!(*names)
¶
(*names)
Defines raise-on-nil and nilable getter methods for each of the given arguments.
Writing:
class Person
class_getter! name
end
Is the same as writing:
class Person
def self.name?
@@name
end
def self.name
@@name.not_nil!
end
end
The arguments can be string literals, symbol literals or plain names:
class Person
class_getter! :name, "age"
end
If a type declaration is given, a variable with that name is declared with that type, as nilable.
class Person
class_getter! name : String
end
is the same as writing:
class Person
@@name : String?
def self.name?
@@name
end
def self.name
@@name.not_nil!
end
end
class_getter?
¶
Defines query getter methods for each of the given arguments.
Writing:
class Person
class_getter? happy
end
Is the same as writing:
class Person
def self.happy?
@@happy
end
end
The arguments can be string literals, symbol literals or plain names:
class Person
class_getter? :happy, "famous"
end
If a type declaration is given, a variable with that name is declared with that type.
class Person
class_getter? happy : Bool
end
is the same as writing:
class Person
@@happy : Bool
def self.happy? : Bool
@@happy
end
end
The type declaration can also include an initial value:
class Person
class_getter? happy : Bool = true
end
Is the same as writing:
class Person
@@happy : Bool = true
def self.happy? : Bool
@@happy
end
end
An assignment can be passed too, but in this case the type of the variable must be easily inferable from the initial value:
class Person
class_getter? happy = true
end
Is the same as writing:
class Person
@@happy = true
def self.happy?
@@happy
end
end
If a block is given to the macro, a getter is generated
with a variable that is lazily initialized with
the block's contents, for examples see #class_getter
.
class_property
¶
Defines property methods for each of the given arguments.
Writing:
class Person
class_property name
end
Is the same as writing:
class Person
def self.name=(@@name)
end
def self.name
@@name
end
end
The arguments can be string literals, symbol literals or plain names:
class Person
class_property :name, "age"
end
If a type declaration is given, a variable with that name is declared with that type.
class Person
class_property name : String
end
Is the same as writing:
class Person
@@name : String
def self.name=(@@name)
end
def self.name
@@name
end
end
The type declaration can also include an initial value:
class Person
class_property name : String = "John Doe"
end
Is the same as writing:
class Person
@@name : String = "John Doe"
def self.name=(@@name : String)
end
def self.name
@@name
end
end
An assignment can be passed too, but in this case the type of the variable must be easily inferable from the initial value:
class Person
class_property name = "John Doe"
end
Is the same as writing:
class Person
@@name = "John Doe"
def self.name=(@@name : String)
end
def self.name
@@name
end
end
If a block is given to the macro, a property is generated with a variable that is lazily initialized with the block's contents:
class Person
class_property(birth_date) { Time.local }
end
Is the same as writing:
class Person
def self.birth_date
if (value = @@birth_date).nil?
@@birth_date = Time.local
else
value
end
end
def self.birth_date=(@@birth_date)
end
end
class_property!(*names)
¶
(*names)
Defines raise-on-nil property methods for each of the given arguments.
Writing:
class Person
class_property! name
end
Is the same as writing:
class Person
def self.name=(@@name)
end
def self.name?
@@name
end
def self.name
@@name.not_nil!
end
end
The arguments can be string literals, symbol literals or plain names:
class Person
class_property! :name, "age"
end
If a type declaration is given, a variable with that name is declared with that type, as nilable.
class Person
class_property! name : String
end
Is the same as writing:
class Person
@@name : String?
def self.name=(@@name)
end
def self.name?
@@name
end
def self.name
@@name.not_nil!
end
end
class_property?
¶
Defines query property methods for each of the given arguments.
Writing:
class Person
class_property? happy
end
Is the same as writing:
class Person
def self.happy=(@@happy)
end
def self.happy?
@@happy
end
end
The arguments can be string literals, symbol literals or plain names:
class Person
class_property? :happy, "famous"
end
If a type declaration is given, a variable with that name is declared with that type.
class Person
class_property? happy : Bool
end
Is the same as writing:
class Person
@@happy : Bool
def self.happy=(@@happy : Bool)
end
def self.happy? : Bool
@@happy
end
end
The type declaration can also include an initial value:
class Person
class_property? happy : Bool = true
end
Is the same as writing:
class Person
@@happy : Bool = true
def self.happy=(@@happy : Bool)
end
def self.happy? : Bool
@@happy
end
end
An assignment can be passed too, but in this case the type of the variable must be easily inferable from the initial value:
class Person
class_property? happy = true
end
Is the same as writing:
class Person
@@happy = true
def self.happy=(@@happy)
end
def self.happy?
@@happy
end
end
If a block is given to the macro, a property is generated
with a variable that is lazily initialized with
the block's contents, for examples see #class_property
.
class_setter(*names)
¶
(*names)
Defines setter methods for each of the given arguments.
Writing:
class Person
class_setter name
end
Is the same as writing:
class Person
def self.name=(@@name)
end
end
The arguments can be string literals, symbol literals or plain names:
class Person
class_setter :name, "age"
end
If a type declaration is given, a variable with that name is declared with that type.
class Person
class_setter name : String
end
is the same as writing:
class Person
@@name : String
def self.name=(@@name : String)
end
end
The type declaration can also include an initial value:
class Person
class_setter name : String = "John Doe"
end
Is the same as writing:
class Person
@@name : String = "John Doe"
def self.name=(@@name : String)
end
end
An assignment can be passed too, but in this case the type of the variable must be easily inferable from the initial value:
class Person
class_setter name = "John Doe"
end
Is the same as writing:
class Person
@@name = "John Doe"
def self.name=(@@name)
end
end
def_clone
¶
Defines a clone
method that returns a copy of this object with all
instance variables cloned (clone
is in turn invoked on them).
def_equals(*fields)
¶
(*fields)
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
def_equals_and_hash(*fields)
¶
(*fields)
Defines hash
and ==
method from the given fields.
The generated ==
method has a self
restriction.
class Person
def initialize(@name, @age)
end
# Define a hash method based on @name and @age
# Define a `==` method that compares @name and @age
def_equals_and_hash @name, @age
end
def_hash(*fields)
¶
(*fields)
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 object)
¶
(*methods, to object)
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"
forward_missing_to(delegate)
¶
(delegate)
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"
getter
¶
Defines getter methods for each of the given arguments.
Writing:
class Person
getter name
end
Is the same as writing:
class Person
def name
@name
end
end
The arguments can be string literals, symbol literals or plain names:
class Person
getter :name, "age"
end
If a type declaration is given, a variable with that name is declared with that type.
class Person
getter name : String
end
Is the same as writing:
class Person
@name : String
def name : String
@name
end
end
The type declaration can also include an initial value:
class Person
getter name : String = "John Doe"
end
Is the same as writing:
class Person
@name : String = "John Doe"
def name : String
@name
end
end
An assignment can be passed too, but in this case the type of the variable must be easily inferable from the initial value:
class Person
getter name = "John Doe"
end
Is the same as writing:
class Person
@name = "John Doe"
def name : String
@name
end
end
If a block is given to the macro, a getter is generated with a variable that is lazily initialized with the block's contents:
class Person
getter(birth_date) { Time.local }
end
Is the same as writing:
class Person
def birth_date
if (value = @birth_date).nil?
@birth_date = Time.local
else
value
end
end
end
getter!(*names)
¶
(*names)
Defines raise-on-nil and nilable getter methods for each of the given arguments.
Writing:
class Person
getter! name
end
Is the same as writing:
class Person
def name?
@name
end
def name
@name.not_nil!
end
end
The arguments can be string literals, symbol literals or plain names:
class Person
getter! :name, "age"
end
If a type declaration is given, a variable with that name is declared with that type, as nilable.
class Person
getter! name : String
end
is the same as writing:
class Person
@name : String?
def name?
@name
end
def name
@name.not_nil!
end
end
getter?
¶
Defines query getter methods for each of the given arguments.
Writing:
class Person
getter? happy
end
Is the same as writing:
class Person
def happy?
@happy
end
end
The arguments can be string literals, symbol literals or plain names:
class Person
getter? :happy, "famous"
end
If a type declaration is given, a variable with that name is declared with that type.
class Person
getter? happy : Bool
end
is the same as writing:
class Person
@happy : Bool
def happy? : Bool
@happy
end
end
The type declaration can also include an initial value:
class Person
getter? happy : Bool = true
end
Is the same as writing:
class Person
@happy : Bool = true
def happy? : Bool
@happy
end
end
An assignment can be passed too, but in this case the type of the variable must be easily inferable from the initial value:
class Person
getter? happy = true
end
Is the same as writing:
class Person
@happy = true
def happy?
@happy
end
end
If a block is given to the macro, a getter is generated
with a variable that is lazily initialized with
the block's contents, for examples see #getter
.
property
¶
Defines property methods for each of the given arguments.
Writing:
class Person
property name
end
Is the same as writing:
class Person
def name=(@name)
end
def name
@name
end
end
The arguments can be string literals, symbol literals or plain names:
class Person
property :name, "age"
end
If a type declaration is given, a variable with that name is declared with that type.
class Person
property name : String
end
Is the same as writing:
class Person
@name : String
def name=(@name)
end
def name
@name
end
end
The type declaration can also include an initial value:
class Person
property name : String = "John Doe"
end
Is the same as writing:
class Person
@name : String = "John Doe"
def name=(@name : String)
end
def name
@name
end
end
An assignment can be passed too, but in this case the type of the variable must be easily inferable from the initial value:
class Person
property name = "John Doe"
end
Is the same as writing:
class Person
@name = "John Doe"
def name=(@name : String)
end
def name
@name
end
end
If a block is given to the macro, a property is generated with a variable that is lazily initialized with the block's contents:
class Person
property(birth_date) { Time.local }
end
Is the same as writing:
class Person
def birth_date
if (value = @birth_date).nil?
@birth_date = Time.local
else
value
end
end
def birth_date=(@birth_date)
end
end
property!(*names)
¶
(*names)
Defines raise-on-nil property methods for each of the given arguments.
Writing:
class Person
property! name
end
Is the same as writing:
class Person
def name=(@name)
end
def name?
@name
end
def name
@name.not_nil!
end
end
The arguments can be string literals, symbol literals or plain names:
class Person
property! :name, "age"
end
If a type declaration is given, a variable with that name is declared with that type, as nilable.
class Person
property! name : String
end
Is the same as writing:
class Person
@name : String?
def name=(@name)
end
def name?
@name
end
def name
@name.not_nil!
end
end
property?
¶
Defines query property methods for each of the given arguments.
Writing:
class Person
property? happy
end
Is the same as writing:
class Person
def happy=(@happy)
end
def happy?
@happy
end
end
The arguments can be string literals, symbol literals or plain names:
class Person
property? :happy, "famous"
end
If a type declaration is given, a variable with that name is declared with that type.
class Person
property? happy : Bool
end
Is the same as writing:
class Person
@happy : Bool
def happy=(@happy : Bool)
end
def happy? : Bool
@happy
end
end
The type declaration can also include an initial value:
class Person
property? happy : Bool = true
end
Is the same as writing:
class Person
@happy : Bool = true
def happy=(@happy : Bool)
end
def happy? : Bool
@happy
end
end
An assignment can be passed too, but in this case the type of the variable must be easily inferable from the initial value:
class Person
property? happy = true
end
Is the same as writing:
class Person
@happy = true
def happy=(@happy)
end
def happy?
@happy
end
end
If a block is given to the macro, a property is generated
with a variable that is lazily initialized with
the block's contents, for examples see #property
.
setter(*names)
¶
(*names)
Defines setter methods for each of the given arguments.
Writing:
class Person
setter name
end
Is the same as writing:
class Person
def name=(@name)
end
end
The arguments can be string literals, symbol literals or plain names:
class Person
setter :name, "age"
end
If a type declaration is given, a variable with that name is declared with that type.
class Person
setter name : String
end
is the same as writing:
class Person
@name : String
def name=(@name : String)
end
end
The type declaration can also include an initial value:
class Person
setter name : String = "John Doe"
end
Is the same as writing:
class Person
@name : String = "John Doe"
def name=(@name : String)
end
end
An assignment can be passed too, but in this case the type of the variable must be easily inferable from the initial value:
class Person
setter name = "John Doe"
end
Is the same as writing:
class Person
@name = "John Doe"
def name=(@name)
end
end