Hi,
I am writing a library for Ruby programmers. What are the issues with adding methods to the Object class? I'm not talking about the practicalities of it -- those are as easy as could be and work. What I am concerned with is the reaction a programmer using that library might have. The benefit is a simplification of a particularly error-prone, tedious, ugly, and repetitive test in the library user's code (that might not show up in unit tests). I don't know what the disadvantages might be, name conflict I suppose. Any others? Any guidelines as to when extending standard classes is considered okay, or not? Is there an expectation in the Ruby culture? is this kind of thing considered rude, or worse?
Cheers,
Bob
···
----
Bob Hutchison -- blogs at <http://www.recursive.ca/hutch/>
Recursive Design Inc. -- <http://www.recursive.ca/>
Raconteur -- <http://www.raconteur.info/>
is there any reason you can't extend the bjectinstead of classes? for
example:
harp:~ > cat a.rb
require 'set'
module ToCSV
def to_csv
to_a.join ','
end
end
array = Array::new
set = Set::new
array << 42 << 'forty-two'
set << 42 << 'forty-two'
array.extend ToCSV
set.extend ToCSV
p array.to_csv
p set.to_csv
harp:~ > ruby a.rb
"42,forty-two"
"forty-two,42"
here neither Array nor Set is affected - only those specific objects.
arrayfields actually works this way and add but a single method to the builtin
Array class which looks something like:
def fields= fields
extend ArrayFields unless ArrayFields === self
@fields = fields
end
this keeps namespace to a minimum. you can also provide factories that do
this:
def csv_dumpable object
obj = object.dup
obj.extend ToCSV
obj
end
puts(csv_dumpable([0,1,2,3,42]))
and various other tricks. if you must pollute built-ins at least pick good
names and add the smallest number of methods possible. yaml does this and
it's fine.
hth.
-a
···
On Tue, 27 Sep 2005, Bob Hutchison wrote:
Hi,
I am writing a library for Ruby programmers. What are the issues with adding
methods to the Object class? I'm not talking about the practicalities of it
-- those are as easy as could be and work. What I am concerned with is the
reaction a programmer using that library might have. The benefit is a
simplification of a particularly error-prone, tedious, ugly, and repetitive
test in the library user's code (that might not show up in unit tests). I
don't know what the disadvantages might be, name conflict I suppose. Any
others? Any guidelines as to when extending standard classes is considered
okay, or not? Is there an expectation in the Ruby culture? is this kind of
thing considered rude, or worse?
Cheers,
Bob
----
Bob Hutchison -- blogs at <http://www.recursive.ca/hutch/>
Recursive Design Inc. -- <http://www.recursive.ca/>
Raconteur -- <http://www.raconteur.info/>
--
email :: ara [dot] t [dot] howard [at] noaa [dot] gov
phone :: 303.497.6469
Your life dwells amoung the causes of death
Like a lamp standing in a strong breeze. --Nagarjuna
===============================================================================
Good suggestion. I gave this a shot. It works for the key bits and pieces *except* for symbols. So, at the moment, I have a configuration option that will determine whether to extend Symbol (only), or will convert symbols to strings.
As I play with it, this is beginning to look like an expensive proposition. Any idea what the overhead to extending an instance with a module is? I think I'm going to have to re-think this.
Thanks for the help.
Cheers,
Bob
···
On Sep 26, 2005, at 6:45 PM, Ara.T.Howard wrote:
On Tue, 27 Sep 2005, Bob Hutchison wrote:
I am writing a library for Ruby programmers. What are the issues with adding
methods to the Object class? I'm not talking about the practicalities of it
-- those are as easy as could be and work. What I am concerned with is the
reaction a programmer using that library might have. The benefit is a
simplification of a particularly error-prone, tedious, ugly, and repetitive
test in the library user's code (that might not show up in unit tests). I
don't know what the disadvantages might be, name conflict I suppose. Any
others? Any guidelines as to when extending standard classes is considered
okay, or not? Is there an expectation in the Ruby culture? is this kind of
thing considered rude, or worse?
is there any reason you can't extend the bjectinstead of classes?
----
Bob Hutchison -- blogs at <http://www.recursive.ca/hutch/>
Recursive Design Inc. -- <http://www.recursive.ca/>
Raconteur -- <http://www.raconteur.info/>
Some quick performance measurements:
class C
end
class CC<C
include Enumerable
end
Benchmark.measure {10000.times{ C.new}}
=> #<Benchmark::Tms:0x106f160 @total=0.0399999999999999, @cutime=0.0,
@label="", @stime=0.0, @real=0.104024171829224,
@utime=0.0399999999999999, @cstime=0.0>
Benchmark.measure {10000.times{ CC.new}}
=> #<Benchmark::Tms:0x103af3c @total=0.04, @cutime=0.0, @label="",
@stime=0.0, @real=0.104261159896851, @utime=0.04, @cstime=0.0>
Benchmark.measure {10000.times{ C.new.extend Enumerable}}
=> #<Benchmark::Tms:0x104c5d4 @total=0.54, @cutime=0.0, @label="",
@stime=0.0, @real=0.683220148086548, @utime=0.54, @cstime=0.0>
So, it looks like better than 10x as expensive to instantiate and
extend as to just instantiate. (Some of my measurements showed more
like 20x.)
However, I wouldn't worry about the performance of extend unless you
have good reason to believe it's a bottleneck.
So, it looks like better than 10x as expensive to instantiate and
extend as to just instantiate. (Some of my measurements showed more
like 20x.)
Oh dear.
Thanks for the information Caleb.
However, I wouldn't worry about the performance of extend unless you
have good reason to believe it's a bottleneck.
Unfortunately in certain cases this will be in a very performance sensitive area (I've spent a lot of time profiling it, wouldn't say it is as optimal as it can be, but chasing after fractions of a percent improvement seems like a waste of time). Fortunately, I can identify these and I can probably deal with it differently (i.e. build a few classes that extend some of the built in classes -- not every class can occur at the critical part). Then in the less critical part extend each object as it comes up (likely less time critical). Symbols still present a problem (they can't be extended it seems).
[As an aside... Here is an example of when a lisp-like macro would come in handy. The trouble with symbols is that they are instantiated before I can get my hands on them, and Symbol instances cannot be extended -- this is a *runtime* issue. In a lisp macro I could scan for the symbol definition at *compile* time, not runtime, and *before* it is evaluated (i.e. instantiated as a Symbol instance) and change the program from a :hello to MySymbol.new("hello") or what-ever. Doing work at compile time only affect compilation time not execution time, and so can be a very good investment. I suppose I could also define a reader-macro and let lisp do the 'scanning' for me -- these are applied at read time which is even before compile time.]
···
On Sep 27, 2005, at 4:43 PM, Caleb Clausen wrote:
----
Bob Hutchison -- blogs at <http://www.recursive.ca/hutch/>
Recursive Design Inc. -- <http://www.recursive.ca/>
Raconteur -- <http://www.raconteur.info/>
In case anyone is interested, I've just published a Ruby oriented article <http://recursive.ca/hutch/index.php?p=243> on my weblog that talks a bit about the project that is motivating my interest in this subject. There are some other articles on the weblog, in the category 'xampl' that are related.
Cheers,
Bob
···
----
Bob Hutchison -- blogs at <http://www.recursive.ca/hutch/>
Recursive Design Inc. -- <http://www.recursive.ca/>
Raconteur -- <http://www.raconteur.info/>