I’m reading the book Hands-on-Design-Patterns-and-Best-Practices-with-Julia
in Vehicle.jl
module Vehicle
# ------------------------------------------------------------------
# 1. Export/Imports
# ------------------------------------------------------------------
export go!, land!
# ------------------------------------------------------------------
# 2. Interface documentation
# ------------------------------------------------------------------
# A vehicle (v) must implement the following functions:
#
# power_on!(v) - turn on the vehicle's engine
# power_off!(v) - turn off the vehicle's engine
# turn!(v, direction) - steer the vehicle to the specified direction
# move!(v, distance) - move the vehicle by the specified distance
# position(v) - returns the (x,y) position of the vehicle
# engage_wheels!(v) - engage wheels for landing. Optional.
# has_wheels(v) - returns true if the vehicle has wheels.
# ------------------------------------------------------------------
# 3. Generic definitions for the interface
# ------------------------------------------------------------------
function power_on! end
function power_off! end
function turn! end
function move! end
function position end
# soft contracts
engage_wheels!(args...) = nothing
# trait
has_wheels(vehicle) = error("Not implemented.")
# ------------------------------------------------------------------
# 4. Game logic
# ------------------------------------------------------------------
# Returns a travel plan from current position to destination
function travel_path(position, destination)
return round(π/6, digits=2), 1000 # just a test
end
# Space travel logic
function go!(vehicle, destination)
power_on!(vehicle)
direction, distance = travel_path(position(vehicle), destination)
turn!(vehicle, direction)
move!(vehicle, distance)
power_off!(vehicle)
nothing
end
# Landing
function land!(vehicle)
engage_wheels!(vehicle)
println("Landing vehicle: ", vehicle)
end
# Landing (using trait)
function land2!(vehicle)
has_wheels(vehicle) && engage_wheels!(vehicle)
println("Landing vehicle: ", vehicle)
end
end # module
in FighterJets.jl
module FighterJets
export FighterJet
"FighterJet is a very fast vehicle with powerful weapons."
mutable struct FighterJet
"power status: true = on, false = off"
power::Bool
"current direction in radians"
direction::Float64
"current position coordinate (x,y)"
position::Tuple{Float64, Float64}
end
# Import generic functions
# I modify the code
include("./Vehicle.jl")
import .Vehicle: power_on!, power_off!, turn!, move!, position
# Implementation of Vehicle interface
function power_on!(fj::FighterJet)
fj.power = true
println("Powered on: ", fj)
nothing
end
function power_off!(fj::FighterJet)
fj.power = false
println("Powered off: ", fj)
nothing
end
function turn!(fj::FighterJet, direction)
fj.direction = direction
println("Changed direction to ", direction, ": ", fj)
nothing
end
function move!(fj::FighterJet, distance)
x, y = fj.position
dx = round(distance * cos(fj.direction), digits = 2)
dy = round(distance * sin(fj.direction), digits = 2)
fj.position = (x + dx, y + dy)
println("Moved (", dx, ",", dy, "): ", fj)
nothing
end
function position(fj::FighterJet)
fj.position
end
end # module
when I try to use it as fellos:
(in the same path, and in a file Try,jl
)
include("./Vehicle.jl")
include("./FighterJets.jl")
# after 1.4 need to add .
using .Vehicle
using .FighterJets
fj = FighterJet(false,0,(0,0))
go!(fj,:mars)
it reports
ERROR: MethodError: no method matching power_on!(::FighterJet)
so I add a line to the FighterJets.jl
export power_on!, power_off!, turn!, move!, position
But it doesn’t work.
- 1 What’s wrong?
Maybe I misunderstand about the path, the module, the scope and the mutidispatch? - 2 is the code
function power_on! end
in module Vehicle is a way to remind/constrain that we must implement the power_on!
function in anther place.