Namespace (ns)#
Every Phel file needs a namespace. Names start with a letter, then letters/numbers/dashes. Parts separated by . (canonical) or \ (legacy, still parses). Last part must match filename.
(ns name imports*)
Sets the namespace and registers imports. :use for PHP classes, :require for Phel modules, :require-file for PHP files.
(ns my.custom.module
(:require-file "vendor/autoload.php")
(:require my.phel.module)
(:use Some.Php.Class))
Also sets *ns* to the namespace.
PHP Coming from PHP? ›
Similar to PHP namespaces, with differences:
// PHP
namespace My\Custom\Module;
use Some\Php\Class;
use My\Phel\Module as Utilities;
// Phel
(ns my.custom.module
(:use Some.Php.Class)
(:require my.phel.module :as utilities))
Differences:
.separator for Phel namespaces (PHP class FQNs in:useuse.):requirefor Phel modules,:usefor PHP classes- Access via
/, not::
Clojure Coming from Clojure? ›
Like Clojure: . namespace separator. PHP class FQNs in :use use ..
:useis for PHP classes:requireworks as in Clojure
Import a Phel module#
Import with :require, then access as module/name. Namespaces resolve from src/ (override with configuration).
Module util in namespace hello-world:
(ns hello-world.util)
(def my-name "Phel")
(defn greet [name]
(print (str "Hello, " name)))
Module main imports util:
(ns hello-world.main
(:require hello-world.util))
(util/greet util/my-name)
Use aliases to avoid collisions:
(ns hello-world.main
(:require hello-world.util :as utilities))
On collision, use a fully-qualified name to reach the original. A locally defined get shadows phel.core/get by its short name, but the full phel.core/get still works:
(ns hello-world.http-client)
(defn get [uri]
{:status 200 :body "Hello World" :headers {}})
(phel.core/get (get "https://example.com") :status) ; Evaluates to 200
:refer brings symbols into the current namespace:
(ns hello-world.main
(:require hello-world.util :refer [greet]))
(greet util/my-name)
:refer and :as combine in any order.
Import a PHP class#
:use imports PHP classes:
(ns my.custom.module
(:use Some.Php.ClassName))
Reference by name:
(ClassName.) ; preferred shorthand
(php/new ClassName) ; also valid
Aliases avoid collisions:
(ns my.custom.module
(:use Some.Php.ClassName :as BetterClassName))
Importing is preferred, but optional. Use full namespace inline if needed:
(php/new Some.Php.ClassName) ; or: (Some.Php.ClassName.)Require PHP files#
Load external PHP files via :require-file (calls require_once). Example for Composer autoload:
(ns hello-world.main
(:require-file "vendor/autoload.php"))
(php/require_once "vendor/autoload.php") works elsewhere, but for autoload it runs too late since Phel's core needs the autoloader. Use :require-file.
Namespaced keywords#
Plain keywords collide when sharing data. Namespaced keywords solve this.
Fully qualified: namespace, /, keyword name.
:my.namespace/foo ; absolute namespaced keyword
:: shortcut binds current namespace:
(ns bar)
::foo ; => :bar/foo
ns aliases also work:
(ns foobar
(:require abc.xyz :as bar))
::bar/foo ; evaluates to :abc.xyz/foo