Skip to content

Namespaced Symbols

Jamie English edited this page Jun 21, 2017 · 2 revisions

Speculation has a global registry for storing specs. This presents the problem of spec name collisions; your 'Users' module may describe an id as a sequence of alphanumeric characters, whereas your 'Payments' module describe an id as an integer. To allow both id specs to inhabit the same spec registry, we namespace them under their relevant modules:

S.def :"User/id", S.and(String, /\A[[:alpha:]+\z/)
S.def :"Payment/id", Integer

The first argument to S.def must be a namespaced symbol. All a Symbol needs to do to be considered namespaced is to include a / between the namespace and the name: <namespace>/<name>. You can write them as Symbol literals as above, or use the provided ns helper:

module User
  extend Speculation::NamespacedSymbols
  S.def ns(:id), S.and(String, /\A[[:alpha:]+\z/)
end

module Payment
  extend Speculation::NamespacedSymbols
  S.def ns(:id), Integer
end

# or alternatively
extend Speculation::NamespacedSymbols

S.def ns(User, :id), S.and(String, /\A[[:alpha:]+\z/)
S.def ns(Payment, :id), Integer
Clone this wiki locally