with statement not triggering opDispatch?

Meta via Digitalmars-d digitalmars-d at puremagic.com
Thu Feb 5 12:46:55 PST 2015


On Thursday, 5 February 2015 at 20:45:36 UTC, Meta wrote:
> On Thursday, 5 February 2015 at 16:27:01 UTC, Alex Parrill 
> wrote:
>> DMD does not seem to consider `opDispatch` when looking up 
>> variables in a `with` block, or . Is this intentional, or a 
>> bug/oversight?
>>
>> For example:
>>
>> 	import std.typecons;
>> 	import std.stdio;
>>
>> 	struct MyStruct {
>> 		auto opDispatch(string name)() {
>> 			return name~"!";
>> 		}
>> 	}
>>
>> 	void main() {
>> 		auto obj = MyStruct();
>> 		with(obj)
>> 			writeln(helloworld());
>> 	}
>>
>> Fails to run with the following error:
>>
>> 	$ rdmd test.d
>> 	test.d(14): Error: undefined identifier helloworld
>> 	Failed: ["dmd", "-v", "-o-", "test.d", "-I."]
>>
>> Even though `helloworld` should be "defined", by way of the 
>> `opDispatch` template.
>>
>> This also occurs when looking up identifiers in methods, when 
>> not prefixing the identifiers with `this`:
>>
>> 	import std.typecons;
>> 	import std.stdio;
>>
>> 	struct MyStruct {
>> 		auto opDispatch(string name)() {
>> 			return name~"!";
>> 		}
>>
>> 		void run() {
>> 			writeln(helloworld()); // Error: no identifier `helloworld`
>> 		}
>> 	}
>>
>> 	void main() {
>> 		auto obj = MyStruct();
>> 		obj.run();
>> 	}
>>
>> I can work around it via introducing a wrapper struct that 
>> contains the wrapped struct and uses `alias this` on it, which 
>> fixes the identifier resolution with methods, but not with 
>> `with`:
>>
>> 	import std.typecons;
>> 	import std.stdio;
>>
>> 	struct MyStruct {
>> 		auto opDispatch(string name)() {
>> 			return name~"!";
>> 		}
>> 	}
>>
>> 	struct MyStructWrapper {
>> 		MyStruct __mystruct;
>> 		alias __mystruct this;
>>
>> 		void run() {
>> 			writeln(helloworld()); // Prints "helloworld!"
>> 		}
>> 	}
>>
>> 	void main() {
>> 		auto obj = MyStructWrapper();
>> 		obj.run();
>> 		with(obj) writeln(helloworld()); // Still fails
>> 	}
>>
>> My use case for this is a D implementation of Mustache that 
>> compiles templates at compile-time, and can be used with 
>> arbitrary objects. The structure maintains the context stack 
>> (stored as a tuple), with `opDispatch` forwarding accesses to 
>> the first object in the stack that contains the named 
>> identifier. The tag content would be retrieved like 
>> `with(context) return mixin(tag_content);`, so that 
>> `{{helloworld}}` would generate `with(context) return 
>> helloworld;`.
>
> This is probably an oversight as nobody's thought to use 
> opDispatch and with in that manner. I don't know what the 
> consensus will be on if it's a bug or not, but you can file an 
> issue at issues.slang.org

That should be issues.dlang.org. I hate smartphones and their 
autocorrect...


More information about the Digitalmars-d mailing list