>  
>  >   
>  
>  
>
>  

str += "1"

This would return a normal string. You'd then have to extend those
strings again and again. Please correct me if I'm wrong but IMHO this
approach brings little advantage over defining a subclass of String:

class MyString < String
    ...
end

str = MyString.new("abc")

This creates a copy of "abc" in this particular case but provides IMHO
more flexibility. With some extra work you could catch those cases
where the function returns a new string, eg something in the line of:

class MyString < BasicObject

    YOUR METHODS HERE

    def method_missing(...)
        ...
    end

end

The extra indirection has its drawbacks of course.

The conclusion IMHO is twofold: (1) "monkey patching" is ok if you're
the only user of your code (in which case it is okay to use a silly
name for that practice) or if the extensions are part of a well
documented supplementary library/framework where those extended
methods become some sort of standard. (2) Beware of people who are
proud of their monkey tactics.