Share your thoughts in the 2024 State of Clojure Survey!

Welcome! Please see the About page for a little more info on how this works.

+15 votes
in Docs by
Pass all args from {{defonce}} on to {{def}} so it supports docstrings (or potentially other future features) just like def.

Docstrings and other Var metadata will be lost when the {{defonce}} is reƫvaluated.

*Patch:* clj-1148-defonce-6.patch

*Screened by:*

17 Answers

+2 votes
by

Comment made by: seancorfield

On noticing that we have a JIRA issue at work to add docstrings to the handful of {{defonce}} calls we have (via alter-meta!), I came upon this issue and wondered what is stopping it moving forward?

Is Linus's patch an acceptable solution overall (and is just missing tests)? Or is a different approach wanted? Is this blocked by CLJ-1446 and folks want that fixed before updating {{defonce}}?

0 votes
by

Comment made by: alexmiller

Changed to defect for stomping metadata.

0 votes
by

Comment made by: stu

Please add tests. The clojure.test-helper namespace has useful temporary namespace support.

0 votes
by

Comment made by: joegallo

This new patch includes the changes to defonce and also tests.

0 votes
by

Comment made by: alexmiller

Changing to Vetted so this is screenable again.

0 votes
by

Comment made by: richhickey

I disagree about the stomp metadata - different metadata was provided. The purpose of defonce is to avoid the re-evaluation of the init. Is this the simplest change that accomplishes the doc string? In any case split in two.

0 votes
by

Comment made by: alexmiller

Reduced scope of ticket to just passing defonce args on to def to add support for docstring. Added new patch that does this.

0 votes
by

Comment made by: stuart.sierra

Screened clj-1148-defonce-2.patch but returning to 'incomplete' status.

The {{:arglists}} metadata in this patch (a list of symbols) is inconsistent with all other uses of {{:arglists}} (a list of vectors).

Other than that the patch is good.

0 votes
by

Comment made by: alexmiller

Updated patch to address inconsistency in arglist format and attached clj-1148-defonce-3.patch.

0 votes
by

Comment made by: stuart.sierra

The patch clj-1148-defonce-3.patch is OK but it doesn't really address the docstring issue because {{defonce}} still destroys metadata. For example:

`
user=> (defonce foo "docstring for foo" (do (prn 42) 42))
42

'user/foo

user=> (doc foo)

user/foo
docstring for foo
nil
user=> (defonce foo "docstring for foo" (do (prn 42) 42))
nil

user=> (doc foo)

user/foo
nil
`

0 votes
by

Comment made by: stuart.sierra

Screened with reservations noted.

0 votes
by

Comment made by: richhickey

Stuart is right, second defonce should retain the doc string (since it again provides it, should be no-op)

0 votes
by

Comment made by: alexmiller

pull out of 1.6

0 votes
by

Comment made by: claj

This version looks for previously defined var with {{resolve}}. A repeated defonce won't affect the namespace at all if the variable is already defined and bounded.

Please confirm using (resolve '~name) is not a problem w.r.t {{ns}}-bindings or similar.

This patch also contains the tests from {{clj-1148-defonce-3.patch}} as well as the {{:arglists}} property.

(patch 4 missed one def-row, sorry for mailbox noise).

0 votes
by
_Comment made by: claj_

Yet another, simpler version of defonce. No test-cases included.

This version just makes an {{(or (nil? v#) (not (.hasRoot v#))}} test on the resolved variable. If this is true, really define by {{(def ~name ~@args)}} else do nothing.
...