diff --git a/README.md b/README.md index 65efb9b..011a51f 100644 --- a/README.md +++ b/README.md @@ -10,27 +10,28 @@ Provided there is a function `inc` that increments a number in a library follows: ```clojure -(load "https://github.com/carpentry-org/dynlib@0.0.4") +(load "https://github.com/carpentry-org/dynlib@0.0.5") (defn main [] (println* &(=> (DynLib.open "libt.so") - (Maybe.to-result @"Couldn’t open libt.so") (Result.and-then - (fn [lib] (Maybe.to-result (DynLib.get lib "inc") @"Couldn’t load symbol inc"))) + (fn [lib] (DynLib.get lib "inc"))) (Result.map (fn [f] (Int.str (f 1))))))) ``` -We’re using `Result` here to get informative error messages, but this is all -optional. If you want to throw safety out of the window, something like this -could also work—though I wholeheartedly advise against it: +`open` and `get` return `(Result a String)`, so the error branch already +carries the real `dlerror()` message—no need to wrap in `Maybe.to-result`. + +If you want to throw safety out of the window, something like this could also +work—though I wholeheartedly advise against it: ```clojure -(load "https://github.com/carpentry-org/dynlib@0.0.3") +(load "https://github.com/carpentry-org/dynlib@0.0.5") (defn main [] - (let [lib (Maybe.unsafe-from (DynLib.open "libt.so")) - f (Maybe.unsafe-from (DynLib.get lib "inc"))] + (let [lib (Result.unsafe-from-success (DynLib.open "libt.so")) + f (Result.unsafe-from-success (DynLib.get lib "inc"))] (println* &(Int.str (f 1))))) ``` diff --git a/docs/DynLib.html b/docs/DynLib.html index b2b0924..84c5a41 100644 --- a/docs/DynLib.html +++ b/docs/DynLib.html @@ -31,15 +31,13 @@

DynLib is a module for loading shared libraries at runtime. It strives to make code loading and calling dynamically easy.

-
(load "https://github.com/carpentry-org/dynlib@0.0.4")
+
(load "https://github.com/carpentry-org/dynlib@0.0.5")
 
 (defn main []
   (println*
     &(=> (DynLib.open "libt.so")
-         (Maybe.to-result @"Couldn’t open libt.so")
          (Result.and-then
-           (fn [lib] (Maybe.to-result (DynLib.get lib "inc")
-                              @"Couldn’t load symbol inc")))
+           (fn [lib] (DynLib.get lib "inc")))
          (Result.map (fn [f] (Int.str (f 1)))))))
 
@@ -75,13 +73,14 @@

defn

- (Fn [Lib, (Ref String a)] (Maybe b)) + (Fn [Lib, (Ref String a)] (Result b String))

                     (get lib fname)
                 

-

gets a function named fname from a shared library lib.

+

gets a function named fname from a shared library lib. Returns +a Result with the function on success, or the dlerror message on failure.

@@ -95,14 +94,15 @@

defn

- (Fn [Lib, (Ref String a), b] (Maybe c)) + (Fn [Lib, (Ref String a), b] (Result c String))

                     (get-from-module lib md fname)
                 

gets a function named fname from a Carp module md from inside -a shared library lib.

+a shared library lib. Returns a Result with the function on success, or the +dlerror message on failure.

@@ -116,13 +116,14 @@

defn

- (Fn [(Ref String a)] (Maybe Lib)) + (Fn [(Ref String a)] (Result Lib String))

                     (open lib)
                 

-

opens a shared library lib.

+

opens a shared library lib. Returns a Result with the library +handle on success, or the dlerror message on failure.

diff --git a/dynlib.carp b/dynlib.carp index e10c715..24b9abf 100644 --- a/dynlib.carp +++ b/dynlib.carp @@ -5,15 +5,13 @@ strives to make code loading and calling dynamically easy. ``` -(load \"https://github.com/carpentry-org/dynlib@0.0.4\") +(load \"https://github.com/carpentry-org/dynlib@0.0.5\") (defn main [] (println* &(=> (DynLib.open \"libt.so\") - (Maybe.to-result @\"Couldn’t open libt.so\") (Result.and-then - (fn [lib] (Maybe.to-result (DynLib.get lib \"inc\") - @\"Couldn’t load symbol inc\"))) + (fn [lib] (DynLib.get lib \"inc\"))) (Result.map (fn [f] (Int.str (f 1))))))) ```") (defmodule DynLib @@ -32,28 +30,37 @@ strives to make code loading and calling dynamically easy. (register dlsym (Fn [Lib (Ptr CChar)] (Ref a)) "DynLib_dlsym") (hidden dlclose) (register dlclose (Fn [Lib] Int) "dlclose") - (hidden dlerror) - (register dlerror (Fn [] String) "dlerror") + (private dlerror-) + (hidden dlerror-) + (register dlerror- (Fn [] (Ptr CChar)) "dlerror") (hidden valid?) (register valid? (Fn [a] Bool) "DynLib_isvalid") + (private dlerror) + (hidden dlerror) + (defn dlerror [] + (let [err (dlerror-)] + (if (valid? err) (String.from-cstr err) @"unknown error"))) - (doc open "opens a shared library `lib`.") + (doc open "opens a shared library `lib`. Returns a `Result` with the library +handle on success, or the `dlerror` message on failure.") (defn open [lib] (let [l (dlopen (cstr lib) lazy)] - (if (valid? l) (Maybe.Just l) (Maybe.Nothing)))) + (if (valid? l) (Result.Success l) (Result.Error (dlerror))))) - (doc get "gets a function named `fname` from a shared library `lib`.") + (doc get "gets a function named `fname` from a shared library `lib`. Returns +a `Result` with the function on success, or the `dlerror` message on failure.") (defn get [lib fname] (let [f (dlsym lib (cstr fname))] - (if (valid? f) (Maybe.Just @f) (Maybe.Nothing)))) + (if (valid? f) (Result.Success @f) (Result.Error (dlerror))))) (doc get-from-module "gets a function named `fname` from a Carp module `md` from inside -a shared library `lib`.") +a shared library `lib`. Returns a `Result` with the function on success, or the +`dlerror` message on failure.") (defn get-from-module [lib md fname] (let [fqn (fmt "%s_%s" &(Pattern.substitute #"\." md "_" -1) fname) f (dlsym lib (cstr &fqn))] - (if (valid? f) (Maybe.Just @f) (Maybe.Nothing)))) + (if (valid? f) (Result.Success @f) (Result.Error (dlerror))))) (doc close "closes a library `lib`. Either returns nothing or, if an error occurs, it returns the error message.") @@ -63,7 +70,7 @@ occurs, it returns the error message.") (defmacro rebind [lib s] (list 'match (list 'DynLib.get lib (str s)) - '(Maybe.Nothing) - (list 'IO.errorln (String.join ["Failed to find symbol " (str s)])) - '(Maybe.Just s) + '(Result.Error e) + (list 'IO.errorln 'e) + '(Result.Success s) (list set! s 's)))) diff --git a/examples/c_and_carp/example.carp b/examples/c_and_carp/example.carp index f7d0555..7387604 100644 --- a/examples/c_and_carp/example.carp +++ b/examples/c_and_carp/example.carp @@ -3,6 +3,5 @@ (defn main [] (println* &(=> (DynLib.open "libt.so") - (Maybe.to-result @"Couldn’t open libt.so") - (Result.and-then &(fn [lib] (Maybe.to-result (DynLib.get lib "add") @"Couldn’t load symbol"))) + (Result.and-then &(fn [lib] (DynLib.get lib "add"))) (Result.map &(fn [f] (Int.str (f 1 2))))))) diff --git a/examples/carp_and_carp/example.carp b/examples/carp_and_carp/example.carp index 8c8d13b..2469885 100644 --- a/examples/carp_and_carp/example.carp +++ b/examples/carp_and_carp/example.carp @@ -3,8 +3,6 @@ (defn main [] (println* &(=> (DynLib.open "libt.so") - (Maybe.to-result @"Couldn’t open libt.so") (Result.and-then - &(fn [lib] - (Maybe.to-result (DynLib.get-from-module lib "Shared" "add") @"Couldn’t load symbol"))) + &(fn [lib] (DynLib.get-from-module lib "Shared" "add"))) (Result.map &(fn [f] (Int.str (f 1 2)))))))