Using 'def with metadata {:type :anything} throws ClassCastException during printing

Description

Specific to setting :type meta on a var:

If it is intended to forbid setting the :type metadata, then there should be an appropriate error message instead of the ClassCastException.

Cause: This is caused by the printer dispatch function

which ends up calling the default dispatch, which tries to vary-meta.

Solution: Add a check in the default print-method for (instance? clojure.lang.IObj o) before calling vary-meta and fallback to print-simple.

Patch: CLJ-1039-tolerate-misleading-type-metadata-on-var-wh.patch

Screened by: Alex Miller

Environment

Ubuntu, lein 1.7.1 - lein repl

Attachments

1

Activity

Show:

Steve Miner April 14, 2014 at 4:21 PM

On the other hand, the :default print-method probably should be more robust. I think a check for (instance? clojure.lang.IObj o) before calling vary-meta would be appropriate. Added a patch that calls print-simple if the o isn't an IObj. That works around the issue for Var, and seems reasonable for other exotic types. The only downside I can imagine is if someone had a custom print-method but accidentally had a typo in their :type metadata, they will no longer get an error. This was an edge case to begin with so that probably doesn't matter.

Steve Miner April 14, 2014 at 4:13 PM

The :type metadata is used internally by Clojure. For the situation in this bug report, you have to take responsibility for providing a print-method if you put :type metatdata on your var.

This is not a good example, but it shows one way to work around the bug:

Stuart Halloway August 10, 2012 at 7:40 PM

This is caused by the printer dispatch function

which ends up calling the default dispatch, which tries to vary-meta.

Completed

Details

Assignee

Reporter

Labels

Approval

Ok

Patch

Code and Test

Priority

Affects versions

Fix versions

Created August 9, 2012 at 12:05 PM
Updated August 29, 2014 at 6:00 PM
Resolved August 29, 2014 at 6:00 PM