Calculated Properties
Part of the Object Oriented Programming section of Coddy's Lua journey — lesson 15 of 70.
Getters and setters provide access to stored values, but sometimes you need data that doesn't exist as a stored field—it needs to be calculated from other attributes. These are called calculated properties.
Consider a rectangle. You store its width and height, but the area isn't stored anywhere—it's computed by multiplying these two values together. Instead of storing redundant data, you create a method that calculates and returns the result:
local Rectangle = {}
Rectangle.__index = Rectangle
function Rectangle:new(width, height)
local instance = {}
setmetatable(instance, self)
instance.width = width
instance.height = height
return instance
end
function Rectangle:getArea()
return self.width * self.height
endThe :getArea() method doesn't return a stored value—it computes the area fresh each time you call it. This approach has a key advantage: if the width or height changes, the area automatically reflects the new dimensions without you needing to update anything.
local box = Rectangle:new(5, 3)
print(box:getArea()) -- Output: 15
box.width = 10
print(box:getArea()) -- Output: 30Calculated properties keep your objects consistent. Rather than storing values that depend on other fields (and risking them becoming outdated), you compute them on demand. This pattern applies to any derived data—perimeters, averages, formatted strings, or any value that can be determined from existing attributes.
Challenge
EasyLet's build a Box class that calculates its volume on demand! Instead of storing the volume as a field, you'll create a calculated property that computes it from the box's dimensions whenever it's needed.
You'll organize your code across two files:
Box.lua: Define yourBoxclass with the standard prototype pattern. Each box stores three dimensions:width,height, anddepth. Include:- A
:new(width, height, depth)constructor that stores all three dimensions - A
:getVolume()method that calculates and returns the volume (width × height × depth) - A
:getSurfaceArea()method that calculates and returns the total surface area
- A
main.lua: Require your Box module, create a box instance, and demonstrate how the calculated properties automatically reflect the current dimensions.
The surface area of a box is calculated as: 2 × (width×height + height×depth + width×depth)
You will receive three inputs representing the box's dimensions:
- Width
- Height
- Depth
In your main file, create a box with the given dimensions, then print two lines:
- The volume using
:getVolume() - The surface area using
:getSurfaceArea()
For example, if the inputs are 3, 4, and 5, the output should be:
60
94The beauty of calculated properties is that they always stay accurate. If you later changed one of the box's dimensions, calling :getVolume() again would automatically return the correct new value—no manual updates needed!
Cheat sheet
Calculated properties are methods that compute and return values based on other attributes rather than storing them directly. This ensures data consistency and eliminates redundancy.
Example of a calculated property for area:
local Rectangle = {}
Rectangle.__index = Rectangle
function Rectangle:new(width, height)
local instance = {}
setmetatable(instance, self)
instance.width = width
instance.height = height
return instance
end
function Rectangle:getArea()
return self.width * self.height
endThe :getArea() method calculates the area each time it's called, automatically reflecting any changes to width or height:
local box = Rectangle:new(5, 3)
print(box:getArea()) -- Output: 15
box.width = 10
print(box:getArea()) -- Output: 30Calculated properties are useful for any derived data such as perimeters, volumes, averages, or formatted strings that can be determined from existing attributes.
Try it yourself
-- Require the Box module
local Box = require('Box')
-- Read input dimensions
local width = tonumber(io.read())
local height = tonumber(io.read())
local depth = tonumber(io.read())
-- TODO: Create a box instance with the given dimensions
-- TODO: Print the volume using :getVolume()
-- TODO: Print the surface area using :getSurfaceArea()
This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Object Oriented Programming
1The 'Self' Concept
Tables with FunctionsExplicit 'self'The Colon SyntaxDot vs ColonRecap - Moving Point4Project: Digital Bank
Project SetupDeposit Method7Polymorphism & Overriding
Overriding MethodsCalling Parent MethodsDuck TypingCommon InterfaceChecking TypeRecap - Employee Roles10Project: Shape Manager
Project SetupRectangle Class2Class Prototype Pattern
The Prototype ConceptLinking with __indexThe :new() ConstructorInitializing AttributesIndependent InstancesRecap - Car Factory5Operator Overloading in OOP
Adding ObjectsSubtracting ObjectsConcatenating ObjectsComparing Objects (<, >)Recap - Wallet Math8Encapsulation
Naming ConventionsClosures for PrivacyAccess via ClosuresRead-Only TablesValidation LogicRecap - Secure Vault11Design Patterns (Lite)
Factory FunctionsSingleton TableIterator PatternObserver (Listener)Recap - Logger Factory3Object State and Behavior
Instance VariablesGetter MethodsSetter MethodsCalculated PropertiesFormatting StringsEquality ChecksRecap - Student Grade6Inheritance Basics
The Inheritance SetupInheriting MethodsExtending the ConstructorAdding Child MethodsShared vs UniqueRecap - Shape Hierarchy