Messing with thisContext and the stack is one of those things. When I was implementing the _1:_2:_3:_4:_5: message I was talking about the other day.
The proper and boring way to implement it was like this:
_1: one _2: two _3: three _4: four _5: five
| arguments |
arguments := Array new: 5.
arguments at: 1 put: one.
arguments at: 2 put: two.
arguments at: 3 put: three.
arguments at: 4 put: four.
arguments at: 5 put: five.
^(StringParameterSubstitution default)
originalString: self;
args: arguments;
expandedText
But, I didn't want to do that. That was too much typing I think. I wanted to be clever, so I did this instead:
_1: one _2: two _3: three _4: four _5: five
^(StringParameterSubstitution default)
originalString: self;
args: (thisContext stack copyFrom: 1 to: 5);
expandedText
There are no references to any of the method arguments. Knowing that the stack is already an array with the arguments already placed in them, exactly what I want, I just grab that, instead of making my own array populated with the method arguments.
Don't do this in production code. It's tricky and evil. But sometimes, it's good to remind yourself, or learn from others, what this great environment really is capable of doing. Who knows, having one be aware of it, there may come a point where playing with thisContext or the stack, may help you solve a real problem, in production code, or not.
While I agree that this is a cool demo, what's wrong with
ReplyDelete_1: one _2: two _3: three _4: four _5: five
^(StringParameterSubstitution default)
originalString: self;
args: {one. two. three. four. five};
expandedText
Seems concise enough, yet explicit to me :)