abstract class Object

Overview

Object is the base type of all Crystal objects.

Getters

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.

Type and initial value

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.

Lazy initialization

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

Variants

Please refer to the different variants to understand how they differ from the general overview presented above:

Setters

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.

Properties

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.

Included Modules

Defined in:

spectator/should.cr

Instance Method Summary

Instance Method Detail

def should(matcher : Spectator::Matchers::TypeMatcher(U), message = nil, *, _file = __FILE__, _line = __LINE__) forall U #

Asserts that some criteria defined by the matcher is satisfied. Allows a custom message to be used. Returns the expected value cast as the expected type, if the matcher is satisfied.


[View source]
def should(matcher, message = nil, *, _file = __FILE__, _line = __LINE__) #

Extension method to create an expectation for an object. This is part of the spec DSL and mimics Crystal Spec's default should-syntax. A matcher should immediately follow this method, or be the only argument to it. Example usage:

it "equals the expected value" do
  subject.should eq(42)
end

An optional message can be used in case the expectation fails. It can be a string or proc returning a string.

subject.should_not be_nil, "Shouldn't be nil"

NOTE By default, the should-syntax is disabled. The expect-syntax is preferred, since it doesn't monkey-patch all objects. To enable should-syntax, add the following to your spec_helper.cr file:

require "spectator/should"

[View source]
def should_eventually(matcher, message = nil, *, _file = __FILE__, _line = __LINE__) #

Works the same as #should except that the condition check is postponed. The expectation is checked after the example finishes and all hooks have run.


[View source]
def should_never(matcher, message = nil, *, _file = __FILE__, _line = __LINE__) #

Works the same as #should_not except that the condition check is postponed. The expectation is checked after the example finishes and all hooks have run.


[View source]
def should_not(matcher : Spectator::Matchers::TypeMatcher(U), message = nil, *, _file = __FILE__, _line = __LINE__) forall U #

Asserts that some criteria defined by the matcher is not satisfied. Allows a custom message to be used. Returns the expected value cast without the unexpected type, if the matcher is satisfied.


[View source]
def should_not(matcher : Spectator::Matchers::NilMatcher, message = nil, *, _file = __FILE__, _line = __LINE__) #

Asserts that some criteria defined by the matcher is not satisfied. Allows a custom message to be used. Returns the expected value cast as a non-nillable type, if the matcher is satisfied.


[View source]
def should_not(matcher, message = nil, *, _file = __FILE__, _line = __LINE__) #

Works the same as #should except the condition is inverted. When #should succeeds, this method will fail, and vice-versa.


[View source]