> =A0 =A0module MyGsubBang
> =A0 =A0 =A0def gsub!(*args, &block)
> =A0 =A0 =A0 =A0super(*args, &block) || self
> =A0 =A0 =A0end
> =A0 =A0end
>
> =A0 =A0str =3D "abc".extend(MyGsubBang)

str +=3D "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 =3D 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.