Summary

In this lesson, you learned that:

  • A table can hold functions next to its data. Such a table is an object. function farm.describe(f) … end is short for farm.describe = function(f) … end. string and math are tables of functions, too.
  • The colon passes the object itself: crop:grow() is short for crop.grow(crop), and function crop:grow() for function crop.grow(self). Inside such a method, self is the object it was called on. A dot instead of the colon in the call gives attempt to index a nil value (local 'self').
  • A constructor is a function that creates an object and returns it. Without return, you get nil: attempt to index a nil value (local 'carrot').
  • setmetatable(t, mt) gives a table a metatable. Its __index says where to look for keys that t doesn't have. That's how objects share methods, and how a text finds string.upper for s:upper().
  • A class is a table that holds the methods and is the metatable of its instances: local Crop = {}, Crop.__index = Crop, a constructor Crop.new that calls setmetatable(crop, Crop), and methods such as function Crop:grow(). Without Crop.__index = Crop, you get attempt to call a nil value (method 'grow').
  • Metamethods make objects work with the rest of Lua: __tostring with print and tostring (but not with ..), __eq with ==, __lt with <, > and table.sort, __le with <= and >=, and __add with +.
  • A class inherits from another with setmetatable(Tree, {__index = Crop}). Its constructor calls the parent's constructor and then setmetatable(tree, Tree). A method with the same name overrides the parent's, and Crop.describe(self) calls the parent's version. Metamethods aren't inherited.

In the next lesson, Coroutines, you'll write functions that can pause in the middle and continue later, for example for a character who does one thing each day.

But first, put this lesson together. Emma is selling at the market, and the program in the editor uses a class Product that doesn't exist yet, so it ends with attempt to index a nil value (global 'Product').

Instructions

Above stall, write the class Product. Its constructor Product.new(name, price, count) creates a product with these three keys, and its __tostring describes it as below. The program prints:

Pumpkin: 3 left, 20 coins each
Carrot: 10 left, 5 coins each
Strawberry: 6 left, 12 coins each

Add a method Product:sell(amount). It sells amount pieces, but never more than are left, and returns the coins Emma gets for them. Below the loop, sell 2 pumpkins and 15 carrots (only 10 are left), add up the coins, and print them:

Coins: 90

In the evening, Emma wants to see what's left, cheapest first. Add __lt to Product so that it compares prices, sort the stall with table.sort, and print it again. The program ends like this:

Coins: 90
Carrot: 0 left, 5 coins each
Strawberry: 6 left, 12 coins each
Pumpkin: 1 left, 20 coins each

Start programming for free

By signing up, you agree to the Terms of Service and Privacy Policy.

Or sign up with:

9/9