Thread overview | |||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
January 04, 2014 Is it possible to handle 'magic' property assignments a'la PHP? | ||||
---|---|---|---|---|
| ||||
In D is it possible to handle accessing class properties that don't exist, similar to PHP's magic methods? http://www.php.net/manual/en/language.oop5.overloading.php#object.set For example, the below class doesn't have the 'x' property: class T { this() { this.x = "hello world!"; } } Can i handle this in a programmatic way to intercept the property and deal with it? Something like this: class T { this() { this.x = "hello world!"; } opMagic(A, B)(A property, B value) { // property = "x", value = "hello world!" } } |
January 04, 2014 Re: Is it possible to handle 'magic' property assignments a'la PHP? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Gary Willoughby | On Saturday, 4 January 2014 at 19:08:45 UTC, Gary Willoughby wrote: > In D is it possible to handle accessing class properties that don't exist, similar to PHP's magic methods? > > http://www.php.net/manual/en/language.oop5.overloading.php#object.set > > For example, the below class doesn't have the 'x' property: > > class T > { > this() > { > this.x = "hello world!"; > } > } > > Can i handle this in a programmatic way to intercept the property and deal with it? > > Something like this: > > class T > { > this() > { > this.x = "hello world!"; > } > > opMagic(A, B)(A property, B value) > { > // property = "x", value = "hello world!" > } > } OMG i've just found opDispatch! http://dlang.org/operatoroverloading.html#Dispatch Fantastic! |
January 04, 2014 Re: Is it possible to handle 'magic' property assignments a'la PHP? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Gary Willoughby | On Saturday, 4 January 2014 at 19:17:31 UTC, Gary Willoughby wrote:
> OMG i've just found opDispatch!
>
> http://dlang.org/operatoroverloading.html#Dispatch
>
> Fantastic!
How to handle returning a value from a non-existent property?
|
January 04, 2014 Re: Is it possible to handle 'magic' property assignments a'la PHP? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Gary Willoughby | On Saturday, 4 January 2014 at 19:19:43 UTC, Gary Willoughby wrote:
> On Saturday, 4 January 2014 at 19:17:31 UTC, Gary Willoughby wrote:
>> OMG i've just found opDispatch!
>>
>> http://dlang.org/operatoroverloading.html#Dispatch
>>
>> Fantastic!
>
> How to handle returning a value from a non-existent property?
Got it!
public void opDispatch(string s)(string value)
{
// handle.
}
public string opDispatch(string s)()
{
return "value";
}
|
January 04, 2014 Re: Is it possible to handle 'magic' property assignments a'la PHP? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Gary Willoughby | On Saturday, 4 January 2014 at 19:26:50 UTC, Gary Willoughby wrote: > Got it! opDispatch rox, and there's all kinds of crazy stuff you can do with it. In my dom.d, I used it for three things: https://github.com/adamdruppe/misc-stuff-including-D-programming-language-web-stuff/blob/master/dom.d 1) easy access to attributes (node.href = "dlang.org"; and auto href = node.href;) using the technique you just showed. 2) the style stuff, which does a little rewriting: node.style.marginLeft = "10px"; -> adds "margin-left: 10px;" to the style attribute 3) Forwarding collections: document[".cool"].addClass("cool2"); uses opDispatch to forward any method to the collection without me writing much boilerplate code. This is also nice for calling external dynamic apis, you can use opDispatch to forward over a network call or something like that. I also used it in my jsvar.d file to make a var type in D, very similar to in Javascript: https://github.com/adamdruppe/misc-stuff-including-D-programming-language-web-stuff/blob/master/jsvar.d var a = var.emptyObject; a.cool = { writeln("hello world!"); } a.cool()(); // double parens needed due to broken @property a.bar = 10; writeln(a.bar); // works and so on. D rox so much. |
January 04, 2014 Re: Is it possible to handle 'magic' property assignments a'la PHP? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Adam D. Ruppe | On Sat, Jan 04, 2014 at 07:52:11PM +0000, Adam D. Ruppe wrote: > On Saturday, 4 January 2014 at 19:26:50 UTC, Gary Willoughby wrote: > >Got it! > > opDispatch rox, and there's all kinds of crazy stuff you can do with it. In my dom.d, I used it for three things: [...] Somebody has also used opDispatch to do vector swizzling, such that: auto v = vec.wxzy; is equivalent to: auto v = [vec[0], vec[1], vec[2], vec[1]]; It's also possible to implement Roman numerals with opDispatch that doesn't require a string literal: Roman.II == 2 Roman.VII == 7 ... etc. by parsing the identifier passed to opDispatch at compile-time. Of course, these are arguably clever hacks than true, properly-motivated examples, but still, they exemplify what Andrei meant when he said that the power of opDispatch is largely still unexplored territory. T -- It's amazing how careful choice of punctuation can leave you hanging: |
January 05, 2014 Re: Is it possible to handle 'magic' property assignments a'la PHP? | ||||
---|---|---|---|---|
| ||||
On Sat, Jan 4, 2014 at 10:08 PM, H. S. Teoh <hsteoh@quickfur.ath.cx> wrote:
> Of course, these are arguably clever hacks than true, properly-motivated examples, but still, they exemplify what Andrei meant when he said that the power of opDispatch is largely still unexplored territory.
As Adam showed, it's very nice to make some clean API (or DSL).
Another example I like is generating queries:
auto result = table.findByFirstName;
If Table has a "FirstName" field, then opDispatch will catch any findByXXXXX and generate the related query. A bit like Activerecord for Ruby.
|
January 05, 2014 Re: Is it possible to handle 'magic' property assignments a'la PHP? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Philippe Sigaud | Another simple example that have helped me tremendously when debugging OpenGL calls. A simple dispatcher that checks glGetError after every call. struct GL { auto opDispatch(string name, Args...)(Args args) { enum glName = "gl" ~ name; mixin(format(" static if(is(ReturnType!%1$s == void)) { %1$s(args); checkGLError(); } else { auto r = %1$s(args); checkGLError(); return r; }", glName)); } } GL gl; I simply use gl.funcName instead of glFuncName. opDispatch rules!. |
January 05, 2014 Re: Is it possible to handle 'magic' property assignments a'la PHP? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Philippe Sigaud | On 2014-01-05 14:09, Philippe Sigaud wrote: > As Adam showed, it's very nice to make some clean API (or DSL). > > Another example I like is generating queries: > > auto result = table.findByFirstName; > > If Table has a "FirstName" field, then opDispatch will catch any > findByXXXXX and generate the related query. A bit like Activerecord > for Ruby. Just for the record. In Rails, that's the old, now discourage, Rails 2 syntax. In Rails 3 and later the following syntax is preferred: Table.where(first_name: "foo").first Which in D would look like: Table.where(["first_name": "foo"]).first; -- /Jacob Carlborg |
January 05, 2014 Re: Is it possible to handle 'magic' property assignments a'la PHP? | ||||
---|---|---|---|---|
| ||||
Posted in reply to TheFlyingFiddle | On 01/05/14 15:36, TheFlyingFiddle wrote:
> Another simple example that have helped me tremendously when debugging OpenGL calls. A simple dispatcher that checks glGetError after every call.
>
> struct GL
> {
> auto opDispatch(string name, Args...)(Args args)
> {
> enum glName = "gl" ~ name;
> mixin(format("
> static if(is(ReturnType!%1$s == void))
> {
> %1$s(args);
> checkGLError();
> }
> else
> {
> auto r = %1$s(args);
> checkGLError();
> return r;
> }", glName));
>
> }
> }
> GL gl;
>
> I simply use gl.funcName instead of glFuncName. opDispatch rules!.
While 'void' is not a first class type in D, there /is/ a special case for returning 'void' from functions - so all of the above can simply be written as:
struct gl {
static auto ref opDispatch(string name, Args...)(Args args) {
scope (exit) checkGLError();
return mixin("gl"~name~"(args)");
}
}
artur
|
Copyright © 1999-2021 by the D Language Foundation