Skip to content

Blocks

When a script grows, you’ll find yourself writing the same few lines more than once. A block gives those lines a name so you can use them again.

block sayHello
printline "Hello from a block"
end
sayHello
sayHello
Hello from a block
Hello from a block

block name starts the block and end finishes it. Writing the name calls it. You can also write sayHello() with brackets. They mean the same.

List the inputs after the block’s name. They’re called parameters:

block greet name
printline "Hello, {{name}}"
end
greet "Ada"
greet("Bo")
Hello, Ada
Hello, Bo

Use brackets and commas when there’s more than one parameter:

block describe name age
printline "{{name}} is {{age}}"
end
describe("Ada", 36)
Ada is 36

return ends the block and hands a value back to whoever called it:

block area width height
return width * height
end
set a to area(3, 4)
printline "The area is {{a}}"
The area is 12

A block can return from several places. This one sorts a number into a word:

block describe n
if n is less than 0
return "negative"
end
if n is 0
return "zero"
end
return "positive"
end
printline describe(-2)
printline describe(0)
printline describe(9)
negative
zero
positive

A block that never reaches a return gives back null.

You can call a block with or without brackets: printline describe(9) and printline describe 9 both print the answer. A bracket-less call takes everything to the end of the line, so use brackets when something follows the call: printline describe(9) ~ "!".

Blocks can call each other, and themselves:

block factorial n
if n is less than or equal to 1
return 1
end
return n * factorial(n - 1)
end
printline factorial(5)
120

Remember the blocks you copied in the last chapter? They were the same thing, written inline with no name. You can also pass a named block to map:

block cube n
return n * n * n
end
printline mash.collect([1, 2, 3]).map(cube).join(", ")
1, 8, 27

A block can read and change the variables of the script around it. Its own parameters are private to it:

set name to "outer"
block hi name
printline "inside: {{name}}"
end
hi("param")
printline "outside: {{name}}"
inside: param
outside: outer

But a plain set inside a block changes the script’s variable, and a variable made inside a block is still there afterwards:

set total to 0
block bump
set total to 100
set leftover to 5
end
bump
printline total
printline leftover
100
5

To keep a variable inside the block, start the line with here:

set x to 1
block tryIt
here x = 50
printline "inside: {{x}}"
end
tryIt
printline "outside: {{x}}"
inside: 50
outside: 1

Use here for scratch variables in a block that others might call, so you don’t overwrite something in the script by accident.

Name your blocks differently from your variables

Section titled “Name your blocks differently from your variables”

Don’t give a block and a variable the same name. MaSH won’t stop you, but one will hide the other. Pick clear names: total for a number, calculateTotal for the block.

Write a block called clean that takes some text and returns it trimmed and in lower case. Hint: mash.str(text).trim().lower().toString(). Call it on " Invoice 2041 ".

Next, you’ll make your scripts cope when something goes wrong.