Submitted by RabYak (Mon Jan 26 19:01:49 UTC 2004)
Ruby allows methods named []
or foobar
. I suggest that the language should allow a method named foobar[]
.
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={}
<b>@children = FooBar.new(@childElements,@childrenByName,@childrenById)</b>
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.
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.)
style:italic">Sadly, I am not yet proficient enough in the language to be able to offer a proposed implementation.
Comments | Current voting | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
|
RCRchive copyright © David Alan Black, 2003-2005.
Powered by .
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:
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 BlackDitto 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.