Ruby is hardly expressive at all in this respect - you can express to the interpreter very little about types, and the interpreter won't help you much at all.
> you can express to the interpreter very little about types
Dynamic types are still types. Only the error detection moment is different, but lack of static types doesn't mean low expressivity.
Also, typing is not the end of all the things.
Most languages I listed have much stronger metaprogramming capabilities than C++. Scala, Rust, Template Haskell macro systems are superior to C++ templates.