Skip to content

By coding a Record

We have now enough experience to know that a type is defined to be used in variables declaration.

Let's see how to do it (simple) and how to manage them (less simple but not impossible):

...
John,Mary,Smith : TPlayer;

...
John.Name:='John Dangerous';
SetLength(John.Cards, Length(John.Cards)+4 ); //John has 4 cards
John.Cards[0].Suit:=Spades;
John.Cards[0].Rank:=Ten;
John.Cards[1].Suit:=Hearts;
John.Cards[1].Rank:=Ace;
John.Cards[2].Suit:=Diamonds;
John.Cards[2].Rank:=Two;
John.Cards[3].Suit:=Diamonds;
John.Cards[3].Rank:=Seven;

By using a dot we get access to record's items, with this scheme:
record's-name.item
that can be iterative, just like in example above.

In facts a TPlayer is record whose items are:

  • one string;
  • one record, the TCard we talked about.

If we want to access to a value to the suit of cards of John, we must write:
John.Cards[i].Suit
which we can read as "John, who has some cards, the i-th which can have one possible value among Suit ones".
In code above we access only to assign values.

Now take a look to this code line:

String1 := GetEnumName(TypeInfo(TSuit),integer(John.Cards[2].Suit));

GetEnumName is a function, resulting in a string. Its arguments are two:

  1. a string;
  2. an integer.
Lazarus-Enum-and-Records
Enum and Records

It's interesting to understand how these values are reached.

The first with the TypeInfo function that returns the address where TypeInfo record is "placed": the address is called pointer, an important concept we'll talk about in future.

The second with a casting operation, which you can promote a type to another with (where possible): this presumes that John.Cards[2].Suit has a value already assigned. In this case a string is cast to an integer, because that one occupies less memory space than this one.

At a quick look somebody could think that this function is meaningless, because it's enough to assign the card's value to String1.
Remember that an enumeration type is a predefined collection of constant strings (masks for ordinal numbers), so that it cannot be rewritten nor read just like a common variable:

// Compile Error!! Types incompatible!!
// Trying to assign an enumerated value to a string variable
String1 := John.Cards[2].Suit;

Wrong code above results in an error during compilation because of the try to assign an uncorrect type to a variable of a different one.
Players record has a Cards record which has two enumerated: Suit and Rank.
So GetEnumName does the right thing: it reaches the address of the enumerated type, and uses the integer cast string value of John.Cards[2].Suit to return the Suit string related to the integer found.

Last but not least:

// Error!! Not ordinal!!
Type
  EnumType = (one, two, three, forty := 40, thirty := 30);

will result in an obvious error during compilation.