Comment on this RCR (edit wiki page) | 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.


Vote for this RCR

Strongly opposed [4]
Opposed [5]
Neutral [0]
In favor [1]
Strongly advocate [0]

Change the status of this RCR to:

accepted

rejected

withdrawn


Add comments here

It seems to me that obj.foobar[x] already has an interpretation. I would be reluctant to add yet another meaning to a perfectly good expression. -- Jim Weirich


I agree. Even if it's possible to get the parser to do a kind of "fall-through" interpretation of the expression, I don't want to be unable to know what it means by looking at it.

Also, RabYak, I know your particular example isn't the entirety of your thinking about this, but I think the code in the example creates a problem that isn't really there. If you try putting more of the "action" in classes, I think you can make the design more flexible and scaleable. For example, you might create a Child class:

class Child
  def initialize(name,id)
    @name, @id = name, id
  end
end
then maybe a specialized Children container (that knows how to sort and present its elements on criteria of name and id), and so on. -- David Black
Ditto to Jim and David.

I don't feel this problem is big enough to add new syntax and to introduce ambiguity and incompatibility. My solution for this particular problem is in .

Three consequent objection might discourage you, but it always happens in the design process of a language. --matz.

Back to RCRchive.


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