It’s a smart and simple way to run code by function.
If you’re visiting here it’s because you’re already sold on Swift as a great language for apps, but have you ever considered using it for scripting? If not, a new GitHub project from Yonas Kolb is here to convince you otherwise: it’s called Beak and it lets your run Swift code straight from the command line.
To get started, run these three commands from your Mac’s terminal:
git clone https://github.com/yonaskolb/Beak.git
cd Beak
swift run beak run install
That builds and installs Beak, which means it’s ready to run any Swift scripts you need.
Let’s try it out now. Create a new Swift file on your desktop called factors.swift and give it this content:
import Foundation
public func calculate() {
let number = 100
let factors = (1...number).filter { number % $0 == 0 }
print(factors.reduce("Factors: ") { $0 + String($1) + " " })
}
That creates a single function called calculate()
, which creates an array of numbers that divide equally into 100, then prints them out as a single string.
To run that using Beak you need to write a command that does the following:
Run this command now:
beak --path factors.swift run calculate
You specify the function name you want to run, so a single Swift script can contain as many related functions as you want.
As well as run
you can also use list
to show the list of available functions:
beak --path factors.swift list
That will show you there’s only function available, which is our calculate()
function.
Tip: Beak can only see functions that are marked as public
. If you want a function for internal use only – i.e., not exposed by the list
command – just don’t declare it as public
.
Right now our function uses a hard-coded input value, but Beak can process arguments from the command-line and convert them into function arguments.
Try changing the function to this:
public func calculate(number: Int) {
let factors = (1...number).filter { number % $0 == 0 }
print(factors.reduce("Factors: ") { $0 + String($1) + " " })
}
When using the calculate()
method now, you need to run it like this:
beak --path factors.swift run calculate --number 1000
Now that we have a command that takes input, you might want to try using the “function” option for Beak, which provides more details on a specific function. For example:
beak --path factors.swift function calculate
That will say calculate()
takes one argument called number
, which is an Int
. However, if you want more useful output you should add some Markdown comments to your code, like this:
/// Calculates the factors for a given number
/// - Parameters:
/// - number: the input number to use
public func calculate(number: Int) {
let factors = (1...number).filter { number % $0 == 0 }
print(factors.reduce("Factors: ") { $0 + String($1) + " " })
}
These comments are exactly the same format used by Xcode and other Swift tools, so you should already be familiar with them – if not, now would be a good time to investigate my Pro Swift book! If you run Beak’s “function” command now you’ll get much more useful help.
At this point I hope you’re certainly curious to try Swift scripting yourself, but before we’re done I want to demonstrate one last, important feature: cleaning up the commands.
So far we’ve been using commands like this one:
beak --path factors.swift run calculate --number 1000
While it’s certainly nice and clear, it’s also supremely clumsy. Fortunately Beak supports shebang lines, which means you can add a special line to the start of your Swift scripts that allows you to make your scripts into standalone commands.
Modify factors.swift to this:
#!/usr/bin/env beak run --path
import Foundation
/// Calculates the factors for a given number
/// - Parameters:
/// - number: the input number to use
public func calculate(number: Int) {
let factors = (1...number).filter { number % $0 == 0 }
print(factors.reduce("Factors: ") { $0 + String($1) + " " })
}
That first line is the shebang line: it tells Unix systems that the rest of this file should be passed to Beak as its input.
Now run this command from your terminal:
chmod a+x factors.swift
That marks factors.swift as being executable (X) for all (A) users. You can now run this instead:
./factors.swift calculate --number 100
That’s slightly better, but now try running this command:
mv factors.swift /usr/local/bin/factors
That moves factors.swift to the directory containing your local commands, while also renaming it just to “factors”.
Now your command becomes this:
factors calculate --number 100
To make it even shorter (because why not?), you can mark the parameter as unnamed like this:
public func calculate(_ number: Int) {
(Note: make sure you edit /usr/local/bin/factors!)
Because the parameter is unnamed, you no longer need to specify --number
on the command line. So, your command becomes just this:
factors calculate 100
I think you’ll agree that’s much easier to remember!
So, go and give Beak a try. Swift is slowly evolving into a full-stack language (Server-Side Swift, anyone?), and Beak is just one more great step in that direction.
Link: Beak
SPONSORED Take the pain out of configuring and testing your paywalls. RevenueCat's Paywalls allow you to remotely configure and A/B test your entire paywall UI without any code changes or app updates.
Sponsor Hacking with Swift and reach the world's largest Swift community!
Link copied to your pasteboard.