Assumptions about the core API

I was going to add Module#abstract and Array#shuffle in a module I am
writing but then I thought:

  1. Is that good style? Could I break the libraries the module uses (or
    some future release of them) if they already defined those methods?

  2. The other way around: People using my module might modify some core
    API or define the methods I added with a side effect that breaks my
    code?

How do you normally handle this kind of modifications? Is there a way to
change the core API in kind of a local manner? If not, do you document
it, or do you just avoid it?

– fxn

I was going to add Module#abstract and Array#shuffle in a module I am
writing but then I thought:

  1. Is that good style? Could I break the libraries the module uses (or
    some future release of them) if they already defined those methods?

My opinion is that it is bad style, unless you are adding a method to a
class with the intention of being able to dispatch based on the type of
the receiver. For example, YAML adds Array#to_yaml, but it’s
appropriate, because:

  1. the name is not likely to clash with the same method in another
    library
  2. it’s added to Array because it allows the user to write
    obj.to_yaml() without having to know what type obj is; the
    appropriate method gets called depending on what obj’s class is.

However I’ve seen lots of code where people just add a method to Array
when it would be sufficient to have a method in their own class (and
namespace) that does the same thing. That just doesn’t make good sense
to me, because of the risk of clashing with another library (or with a
future version of Ruby).

  1. The other way around: People using my module might modify some core
    API or define the methods I added with a side effect that breaks my
    code?

It is particularly annoying to see code that changes a builtin method to
have slightly different semantics. I think there are valid reasons to
do this (I’ve done it myself on occasion), but they are few and far
between.

How do you normally handle this kind of modifications? Is there a way to
change the core API in kind of a local manner? If not, do you document
it, or do you just avoid it?

There is no good answer to this question, I think.

David Simmons proposed using selector namespaces; see [ruby-talk:26362]
and [ruby-talk:23144]. I think this would be a very nice solution for
Ruby.

David Allen Black wrote a library called Ruby Behaviors that allows
certain semantic changes to the ruby core library to be turned on and
off at will. Unfortunately, it has some thread-safety issues that
cannot be solved. See http://uweb.superlink.net/~dblack/ruby/behaviors/
for details. I think someone else wrote a similar library that claimed
to solve some of the thread issues, but I can’t seem to find it now.

Mauricio FernáÏdez has suggested using copies of the builtin classes.
See [ruby-talk:72827]. It’s possible with this method to either a)
copy the builtin class at startup so if someone makes changes to the
builtin class they don’t affect you, or b) to make changes to the copy
and leave the builtin class alone. There are some gotchas with this
solution, though.

Paul

···

On Sat, Sep 13, 2003 at 08:40:29PM +0900, Xavier Noria wrote: