So I don't have a model called Person, but I use hashes like {:name => "Siddharth", :sex => "Y"}. Great. Now I want to validate the presence of certain fields before persisting to the database. What do I do?
Module PersonValidation
function validate_presence_of_name(person_hash)
person_hash[:errors][:name] = "EEENKKK!" unless person_hash[:name]
end
...
...
end
So I must be missing something because how is this different from a class in a dynamic language? The above approach means you can easily swap out functions in one module for another and thus not tie the validation implementation to the structure of the loan hash, but this is trivially simple in Ruby even using classes. Is there some other benefit?
Clojure maps (aka hashes) are suitable for modelling domain values when you don't need fast type based, polymorphic dispatch (which is most of the times for me, but YMMV). If you don't need type based dispatch, you could just use maps. Then your domain values will be able to participate in Clojure's sequence abstractions without much hassle. You could stick in the validator functions, for example, in the metadata like this -
You can then write a generic function which can persist any entity after validating it -
Note that in here the persist-to-db! function will throw an exception if the precondition fails. This is just an example, you don't really need to use it like so.
All of this is still better than a class because of two reasons -
Also, take a look at Trammel, a very nice contracts-programming library for Clojure.
You can also use Clojure's
defrecord
feature to create map-like types and introduce similar validation behaviour usingprotocols
.PS - When you talk about "swapping out functions" from classes in Ruby being trivial, do you mean Monkey Patching?