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)))))))