-
-
Notifications
You must be signed in to change notification settings - Fork 8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature enhancement: float options #9
Comments
Hey @rpgoldman , Here's how you can create a new option (feel free to submit a PR for it): The code, which implements a new
Here's what the code looks like. ;; Load systems
(ql:quickload :clingon)
(ql:quickload :parse-float)
;; Our sample package
(defpackage :clingon.extensions/option-float
(:use :cl)
(:import-from :parse-float)
(:import-from
:clingon
:option
:make-option
:option-derive-error
:initialize-option
:option-value
:derive-option-value)
(:export
:option-float
:option-float-radix
:parse-float-or-lose))
(in-package :clingon.extensions/option-float)
(defun parse-float-or-lose (value &key (radix 10))
(when (floatp value)
(return-from parse-float-or-lose value))
(let ((f (parse-float:parse-float value :radix radix :junk-allowed t)))
(unless f
(error 'option-derive-error :reason (format nil "Cannot parse ~A as float" value)))
f))
(defclass option-float (option)
((radix
:initarg :radix
:initform 10
:reader option-float-radix))
(:default-initargs
:parameter "FLOAT")
(:documentation "An option class to represent float numbers"))
(defmethod make-option ((kind (eql :float)) &rest rest)
(apply #'make-instance 'option-float rest))
(defmethod initialize-option ((option option-float) &key)
"Initializes our option"
;; Make sure to invoke our parent initialization method first, so
;; various things like setting up initial value from environment
;; variables can still be applied.
(call-next-method)
;; If we don't have any value set, there's nothing else to
;; initialize further here.
(unless (option-value option)
(return-from initialize-option))
;; If we get to this point, that means we've got some initial value,
;; which is either set as a default, or via environment
;; variables. Next thing we need to do is make sure we've got a good
;; initial value, so let's derive a value from it.
(let ((current (option-value option)))
(setf (option-value option)
(derive-option-value option current))))
(defmethod derive-option-value ((option option-float) value &key)
(let ((radix (option-float-radix option)))
(parse-float-or-lose value :radix radix))) And testing it out on the REPL. CL-USER> (defparameter *opt*
(clingon:make-option :float :short-name #\f :key :my-float :description "some float"))
*OPT*
CL-USER> (clingon:derive-option-value *opt* "10")
10.0
CL-USER> (clingon:derive-option-value *opt* "10e-2")
0.1 (10.0%)
CL-USER> (clingon:derive-option-value *opt* "1.2e-3")
0.0012 (0.120000005%) You can also check #2 for additional examples about new options. Feel free to add anything else to this code and submit it as a PR! :) |
Thanks for that. I will push it onto my todo list, and hope to get to it pretty soon... |
For scientific / numerical options, it would be very helpful to have options that accept floating point (decimal number) values.
For now, I hack around this by using
:string
and then parsing it myself. I wasn't confident I could add a new option type myself.The text was updated successfully, but these errors were encountered: