6
votes

In Racket, if you try to hash-ref for a key the hash does not contain, e.g.

(define a-hash #hash((1 . "a")
                     (2 . "b")))
(hash-ref a-hash 3)

An exn:fail:contract is raised.

...\Racket\collects\racket\private\more-scheme.rkt:263:2: hash-ref: no value found for key

Unfortunately, exn:fail:contract is unhelpfully broad. It's the same type of exception you get if you try to apply a value as a procedure

(with-handlers ((exn:fail? print))
  (10 11))

(exn:fail:contract "application: not a procedure;\n expected a procedure that can be applied to arguments\n given: 10\n arguments...:\n 11" #)

Is there any way to change the default value of hash-ref's failure-result from outside the code using it? Could I go into my Racket installation and change it there? That seems Bad and Dangerous. What are my options? I could parse the exception message, but that reeks of hacky and error-prone.

1
Are you unable to pass in a different failure-result?stchang
I'm not calling hash-ref directly, I'm calling code that calls itMatt G
Ah ok. I would file a bug against the code that calls hash-ref then.stchang
I think a default value should be general. But that is why hash-ref allows the programmer to give a different failure-result. Are you looking at a specific library in Racket?stchang
OK. Reason I looked there was to try to guess the answer to stchang's question to you: What function are you calling that in turn calls hash-ref? Because really this seems like a situation where that function doesn't expect hash-ref to fail -- and that's the place to change. Otherwise, I don't think you can monkey-patch hash-ref in the way you wondered. Which leaves only the option of the exn msg parse hack idea.Greg Hendershott

1 Answers

0
votes

There is failure-result in hash-ref.

(define a-hash #hash((1 . "a")
                     (2 . "b")))
(hash-ref a-hash 3 #f) ; => #f