loading...

Flexible Ruby Value Object Initialisation

MetaDave 🇪🇺 on January 21, 2019

Problem Value objects in Ruby are lovely things, and invaluable in a complex application. But one issue that always seems to trip me... [Read Full]
markdown guide
 

Nice use of refinements. I've not seen them around much, but this is a good example of how they can really clean up an approach.

 

Thanks Phil. I like the way they put the Ruby core objects on a level playing field with your own application objects, and let them add the behaviour you want.

Having said that, I'd probably draw a line at doing anything like:

module EasyFinder
  refine Integer do
    def to_book
      Book.find(self)
    end
  end

  refine String do
    def to_book
      Book.find(self.to_i)
    end
  end
end

... if I thought anyone was ever going to see my code.

I like the semantics, but it's a bit "out there".

In itself, adding responses to a class clearly does not constitute type checking, it is simply "adding responses to a class".

So are you saying that needing to reference the module that adds the behaviour constitutes a form of type checking?

Refinements depend on the type

Everything in some way depends on the type, because the type defines the messages that can be received and the responses. That is not type checking, though, that is just code.

Other types, no matter whether they respond to / implement this functionality are rejected

If they respond to the correct message then they are not rejected by my ISBN class, because my ISBN class is not type checking. The refinements are just a way of adding the required responses that is safer than monkey patching, but ultimately they just define behaviour.

I would be keen on hearing other opinions, though.

 

Super enlightening Ruby post 👌

Yes, it is a duck check, but I don't want a type check or a duck check. Or any kind of check, really.

What I'm describing is how to achieve the aim of not doing those checks. If that is not an aim that someone shares then they of course are free to implement a different methodology.

 

Indeed, Ruby does conversions very well, as you show in the first code sample.

I do like case, but again it's a type check. I'd rather avoid them if I can. It's good code that, though.

I don't see it as anything other than enabling 100% duck typing in the application. I'm ensuring that the application depends only on the ability to respond, not on the underlying object type.

code of conduct - report abuse