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={}
@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.
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.)
Sadly, I am not yet proficient enough in the language to be able to offer a proposed implementation.
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
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
endthen 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
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