4 ms·
I'm not arguing against abstraction. I'm arguing that explicitly wiring between components is better than implicit. To make this concrete, take the example of
by aston 18y ago
I'm not arguing against abstraction. I'm arguing that explicitly wiring between components is better than implicit.
To make this concrete, take the example of implementing getters for a class in Python. If my class has four fields
class GetterDone:
a = 1
b = 2
c = 3
d = 4
I can do something like this inside the class to implement getters:
def get_a(self):
return self.a
def get_b(self):
return self.b
def get_c(self):
return self.c
def get_d(self):
return self.d
Or I can do something like this:
def __getattr__(self, attr):
if attr.startswith("get_"):
return lambda: getattr(self, attr[4:])
raise AttributeError
The latter does a good job of eliminating boilerplate, but at the cost of making it near impossible for me to find out how get_a() is implemented (assuming this was buried in a huge codebase).
- lisper 18y agoOr you can just realize that get_X is the Wrong Thing and you should just write GetterDoneInstance.X instead.
- aston 18y agoGreat job ignoring the substance. I thought it'd be better to come up with an unrealistic but simple example rather than to paste in the source for Pylons... Just play along and imagine a more complex world. If it makes you happier, pretend the getter is intended to return the string version of the numbers or some other operation that would make just using instance.a wrong.
- lisper 18y agoBut using instance.a is not wrong because you can override __getattr__. And if overriding __getattr__ is not the right thing then what you are writing is not a getter. Under no circumstances is it justified IMHO to write a get_X method. (And if your language doesn't let you override __getattr__ then you need a better language.) IMHO of course.
- DougBTX 18y agoAssuming you know the core Ruby library, would you call this explicit or implicit? class GetterDone attr_reader :a, :b, :c, :d end Rather than being a runtime attr.startswith check, this will generate actual "return self.foo" methods in the class. Think of this as generating code using a UI, except you record the minimal UI commands, rather than putting the full output into your source files. The commands themselves are still explicit, it's just that they contain only the interesting information with the minimum amount of boilerplate.
- aston 18y agoWhat you're talking about is essentially a syntax specifically for getters, I think (I don't know Ruby that well). I guess my general point about "too much magic" goes away when the magic is part of the language, just on semantics. That is, you don't know the language if you don't know what magic its syntax does.
- sofal 18y agoI don't believe that a typical Java IDE provides a clean enough abstraction to make code generation a big benefit. When it comes down to it, you're still looking at a window full of all the code that the IDE spit out for you. Think of code generation via a compiler versus code generation via an IDE. The code that you see in the window of your IDE should be solely for human eyes. If a lot of it can be trivially automated, then it doesn't deserve space in that window.
- stcredzero 18y agoI'm not 100% sure, but attr_reader looks like it's actually a message send. If it's not, then it could be implemented that way.
- LogicHoleFlaw 18y agoYes, it is a plain old method being executed in the context of the current class. It creates new class methods which can be used to read, but not write, instance variables. There are methods to create read-write and (I think? write-only) properties as well.