I don't get why we talk of duck typing about ruby : if I pass as parameter an object that does not quack like a duck, nothing will prevent me to do it and it will generate an exception when quacking. Did I miss something obvious?
I don't get why we talk of duck typing about ruby : if I pass as parameter an object that does not quack like a duck, nothing will prevent me to do it and it will generate an exception when quacking. Did I miss something obvious?
Duck-typing can be boiled down to: The type of a parameter to a function is defined by the methods that will be called on it, not by its class.
E.g. if you have:
def foo source
dosomething(source.shift)
end
Then absent additional restrictions inferred from requirements of dosomething(), the class of "source" is irrelevant. The relevant type information is whether or not "source" responds to "shift".A proper Ruby-ish type checker will need to be able to handle that, or it'll push people to write non-idiomatic Ruby.
But yes, it it a guideline, and Ruby code that violates it will generally be seen as not being idiomatic Ruby.
It makes more sense than talking of duck typing explicit usage by end users, given it's quite rare we assert proper received parameters extensively.
EDIT : which makes me realize we have a machine language without typing (binary), on top of which we use a language implementing strong typing (C), used to build a language without strong typing (ruby), on top of which Stripe is building strong typing. Making a definitive decision is hard :)
C is statically typed, Ruby is dynamic.
Strong typing is about objects having a definite type. In Ruby, you cannot cast a String to a Fixnum, an exception will be raised. But in C you may cast anything to anything really, and your program will believe you, whether it could possibly make sense or not...
(In your example the method could be:
def foo(source: Shiftable<?>)
dosomething(source.shift)
end
where `Shiftable` is an interface that's something like iface Shiftable<T>
.shift(): T
end
)It probably won't be idiomatic (maybe just add interfaces?) but I think duck-typing is overrated anyway. Just because an object responds to a method doesn't mean it's going to do anything like what you expect. To take a contrived example, Array.Shift and Keyboard.Shift are probably unrelated methods.
True, but you can give the interfaces/contracts proper names (or namespaces). To use the example in the parent comment, `Array` and `Keyboard` wouldn’t implement the same contract even if both have a `Shift` method.