logoalt Hacker News

omarqureshitoday at 3:12 AM4 repliesview on HN

I don't programme much any more but the whole beauty of Ruby that it pretty much heavily relies on #respond_to? / duck typing and thus you don't rely on types or class checking at all.


Replies

dymktoday at 3:31 AM

Most ruby code isn't written like that - it's written like most static languages, where objects conform to interfaces / traits / type classes / pick your poison. The community is shifting towards explicitly specifying and statically checking types now. rbs and sorbet are a testament to this.

I wouldn't say it's really a beauty of the language, it may have been the original design intent but time has shown what's actually maintainable.

show 1 reply
systemnatetoday at 4:03 AM

Using #respond_to? is normally a code smell. The point of duck typing is exactly that it allows you to avoid checking the type of a class. As long as the object responds to the correct messages, the type does not matter.

show 1 reply
anamexistoday at 6:09 AM

Structural typing like this is completely compatible with the concept of duck typing. Indeed, it's basically doing static checking of duck typing.

rezonanttoday at 5:24 AM

I don't think you're really losing the ability to check if an object responds to a message ie a_car.respond_to?(:color) just because theres type annotations. And I assume the type checker doesnt yell if you do a_car.color after that -- or if it does there's surely an equivalent to Typescript's `any` to accomplish it.

And T-Ruby apparently provides interfaces to avoid needing to do this at all (assuming both sides are written in T-Ruby I assume) https://type-ruby.github.io/docs/learn/interfaces/defining-i...

...which is awesome!

As for authoring classes, respond_to_missing?/method_missing should be rare, usually in a situation where its the only way to accomplish something. There's never been a reason to write something like:

    class Car
        def respond_to_missing?(name, priv)
            [:color, :color=].include?(name)
        end
        def method_missing(name, *args, &block)
            if name == :color
                @color
            elsif name == :color=
                @color = args.first
            end
        end
    end
Instead of

    class Car
        def color; @color; end
        def color=(value); @color = value; end
    end
Or, more idiomatically

    class Car
        attr_accessor :color
    end
And for that last case, T-Ruby apparently covers it with:

    class Car
        attr_accessor :color: String
    end