Editing Topic: RCR201 Project: RCR | RCRchive home

RCR 201: Method named with string *and* [ ] => def foo[](x)

submitted by RabYak on Mon Jan 26 2004 02:34:49 PM -0800

Status: withdrawn


Abstract

Ruby allows methods named [] or foobar. I suggest that the language should allow a method named foobar[].

Problem

I want to create an accessor method which behaves like a Hash, but which isn't one in the underlying method. For example, say I have:

class HTMLElement
        def initialize
                @childElements=[]
                @childrenByName={}
                @childrenById={}
        end
end

I want to add a way to get at an element by index number, by name, or by ID, all through the same method name and using square-brackets. Currently, the only way to do this (AFAIK) is create a new special class (perhaps inheriting from Hash) with its own [] method, and then create an instance of it for the parent class:

class HTMLElement
        attr_reader(:children)
        def initialize
                @childElements=[]
                @childrenByName={}
                @childrenById={}
                @children = FooBar.new(@childElements,@childrenByName,@childrenById)
        end
end
class FooBar
        def initialize(all,byName,byId)
                @all=all
                @byName=byName
                @byId=byId
        end
        def [](x)
                return @all[x] || @byName[x] || @byId[x]
        end
end

This is bloated and inconvenient.

Proposal

I propose that methods be able to be named foobar[] or foobar[]=. This would allow the previous example to be implemented as:

class HTMLElement
        def initialize
                @childElements=[]
                @childrenByName={}
                @childrenById={}
        end
        def children[](x)
                return @all[x] || @byName[x] || @byId[x]
        end
end

With this change, whenever myObject.foobar[x] is seen, the interpretter first looks for a method with the name foobar[]. If no such method exists, then the current meaning of (myObject.foobar)[x] will be used.

Analysis

This proposal should not affect any existing user code, or built-in objects. (Since no methods exist with this currently-illegal naming scheme, the interpretter will always fall back to the (myObject.foobar)[x] interpretation.) Although it will require a change to the core interpretter of the language, once implemented its only effect should be the addition of functionality. (Functionality which to this novice user seemed logical.)

The only downside I can foresee (other than the time required to implement the feature) is that calls to existing myObject.foobar[x] (where (myObject.foobar)[x] is the desired functionality) //may// become slightly slower, due to the added check for an existing method. (If this is possible at compile time, then no such performance hit would occur.)

Implementation

Sadly, I am not yet proficient enough in the language to be able to offer a proposed implementation.



Back to RCRchive.


RCR Submission page and RCRchive powered by Ruby, Apache, RuWiki (modified), and RubLog