Most times it's better to just accept the dynamic nature of the language rather than do this kind of runtime type checking. You'd have to do this `.is_a?` dance for every type to have it be reliable.
Even if you implement an "interface" (duck typing) with `respond_to?(:to_app_version)` you still can't be sure that the return type of this `:to_app_version` is actually a string you can call `split()` on.