Classes

Classes serve as a template for creating objects.

What is an object?

It is a set of data that allows describing a person, animal, thing or specific concept. You can review the Objects page for more information.

What is the difference between class and object?#

With the class you can create multiple objects that are structurally identical to that class. Each object can have its own independent data.

Objects vs. Classes

Objects are like a photocopy of the class. If you modify the data of an object, it will not affect the other objects. If you modify the class, it will affect all objects that were created from it.

Declaration#

They are declared using two colons :: followed by the class name.

::class_name
  :method_name
    instructions
Indentation

Methods must have more left margin than the class line.

Basic class#

# Class
::Person
  # Method
  :greet
    print "Hello!"

# Object (Instance)
p = Person()

# Method call
p.greet
Instantiation

To create an object from a class, simply call it as if it were a function.

p = Person()

Methods and properties#

The data stored in the object are properties. The functions declared in the class are methods.

a.name = "Ismael"  # This is a property
a.greet()          # This is a method

The self parameter#

Inside any method, you can use self to refer to the object itself. This way you can access its properties at any time.

::Person
  :greet
    print "Hello " self.name

a = Person()
a.name = "Ismael"
a.greet  # Prints "Hello Ismael"
How does self work?
  • Although self appears to be a magic variable. In reality it is simply the first parameter of a method. It is not necessary to write it because DinoCode does it for you:

    ::Person
      :greet self # It is not necessary to write it
        print "Hello " self.name
  • For this reason, when you call a method, DinoCode only passes in its first parameter (which is self) the reference to the object. What in practical terms allows us to play with methods in quite curious ways:

    ::Person
      :greet  # self is added automatically
        print "Hello " self.name
    
    method = Person.greet
    
    # Instead of creating objects using the class
    # We pass to the method a manually created object
    method {name: "Ismael"}
    method {name: "Jessy"}

Constructor :new#

To define initial data each time we create an object, the :new method is used.

::Person
  :new name
    self.name = name
    
a = Person("Ismael")
print a.name
What is the magic method new?

It is a method like any other in the class, but it has a superpower: it executes automatically every time we create an object and also, it receives all the arguments we pass to the class. By itself it does nothing, it only executes, so we need to be explicit about what we want it to do.

Calls in expressions#

Just like with functions, you can omit parentheses in methods only when the context is clear.

::MyClass
  :greet name
    print "Hello " name
  
  :sum a b
    return a + b

a = MyClass()

# Parentheses are not required
a.greet "Ismael"

# Parentheses are required: Classic style
print a.sum(10 5)

# Parentheses are required: Dollar style
print $(a.sum 10 5)
Inference

To understand why delimiters are required or omitted depending on the context, review the Implicit delimiters section.

Chaining#

Methods return self automatically when finished, allowing you to execute several methods of the same object in a single line.

::Person
  :new name
    self.name = name
    
  :greet
    print "Hello " self.name

  :farewell
    print "Goodbye " self.name

a = Person("Ismael")
a.greet().farewell()
Chained methods require delimiters

When chaining methods only the last access can omit delimiters:

# DinoCode infers that it is a greet() method
a.greet

# DinoCode infers that it is a farewell() method
# But is 'greet' a method or property access?
#  - For DinoCode 'greet' is a property access because
#    it is part of the path to reach the 'farewell' method.
a.greet.farewell 

# If 'greet' is a method that must be executed, it is necessary
#  to use delimiters.
a.greet().farewell

Inheritance#

Classes can inherit methods from others. Simply write the name of the class you want to inherit to the right of the new class.

# The base class
::Character
  :new name
    self.name = name

  :greet
    print "Hello, I am " self.name

# Wizard inherits from Character
::Wizard Character
  :cast_spell
    print self.name " cast a fireball! 🔥"

# Warrior also inherits from Character
::Warrior Character
  :attack
    print self.name " used their sword! ⚔️"

player1 = Wizard("Merlin")
player1.greet         # Inherited from Character
player1.cast_spell   # Own to Wizard

player2 = Warrior("Ragnar")
player2.greet         # Inherited from Character
player2.attack          # Own to Warrior
Explicit inheritance of Object

You cannot use the properties and methods of the Object prototype unless you inherit it explicitly.

::MyClass Object
  :greet
    print "Hello"

::OtherClass
  :farewell
    print "Goodbye"

# Works because MyClass inherits from Object
a = MyClass()
a.set "name" "Ismael" # Works
print a.name

# Does not work because OtherClass does not inherit from Object
b = OtherClass()
b.set "name" "Jessy"  # Error