www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Naming methods from strings using mixin

reply "Robert Rouse" <robert.e.rouse gmail.com> writes:
Using a mixin, is it possible to have it define a method based on 
a string passed into the mixin?

An example of what I'm hoping to do:

mixin template make_method(string name) {
      void name() { // not sure how to make it become "void 
bark()" here
        writeln("hello");
      }
}

class Animal {

    mixin make_method!("bark");

}

Animal a;

a.bark();


Any help would be appreciated. I'm hoping D can do this since it 
would make something I'm trying to do easier.
Feb 21 2012
next sibling parent "Adam D. Ruppe" <destructionator gmail.com> writes:
On Tuesday, 21 February 2012 at 14:53:06 UTC, Robert Rouse wrote:
 Using a mixin, is it possible to have it define a method based 
 on a string passed into the mixin?

Yeah, though you'll have to build a string of the method. Something like this: string make_method_string(string name) { string code = "void "; // return type code ~= name; code ~= "() {"; // arglist code ~= q{ // body (q{ } is just another string literal but prettier for this imo writeln("hello"); }; code ~= "}"; return code; } mixin template make_method(string name) { mixin(make_method_string(name)); // string mixin runs the above function at compile time, and then pastes the resulting code in here to be compiled } // and now to use it struct Test { mixin make_method("bark"); } void main() { Test foo; foo.bark(); // works! } The string mixin and string builder helper function pattern can do pretty much anything you can think up, though it can get pretty ugly as it gets bigger just due to being strings.
Feb 21 2012
prev sibling next sibling parent "Vladimir Panteleev" <vladimir thecybershadow.net> writes:
On Tuesday, 21 February 2012 at 14:53:06 UTC, Robert Rouse wrote:
 Using a mixin, is it possible to have it define a method based 
 on a string passed into the mixin?

A simpler way: mixin template MakeMethod(string name) { void _MakeMethod_method() { /* ... */ } mixin("alias _MakeMethod_method " ~ name ~ ";"); }
Feb 21 2012
prev sibling next sibling parent Robert Rouse <robert.e.rouse gmail.com> writes:
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit

Awesome. Thanks!

Adam D. Ruppe wrote:
 On Tuesday, 21 February 2012 at 14:53:06 UTC, Robert Rouse wrote:
 Using a mixin, is it possible to have it define a method based on a
 string passed into the mixin?

Yeah, though you'll have to build a string of the method. Something like this: string make_method_string(string name) { string code = "void "; // return type code ~= name; code ~= "() {"; // arglist code ~= q{ // body (q{ } is just another string literal but prettier for this imo writeln("hello"); }; code ~= "}"; return code; } mixin template make_method(string name) { mixin(make_method_string(name)); // string mixin runs the above function at compile time, and then pastes the resulting code in here to be compiled } // and now to use it struct Test { mixin make_method("bark"); } void main() { Test foo; foo.bark(); // works! } The string mixin and string builder helper function pattern can do pretty much anything you can think up, though it can get pretty ugly as it gets bigger just due to being strings.

Feb 21 2012
prev sibling next sibling parent "Robert Rouse" <robert.e.rouse gmail.com> writes:
Hello again,

Both methods work as long as the object I call the mixin within 
is a struct

struct Test {
   mixin MakeMethod!("bark");
}

If I switch struct to class

class Test {
   mixin MakeMethod!("bark");
}

it segfaults.

What am I missing?



On Tuesday, 21 February 2012 at 15:29:49 UTC, Vladimir Panteleev 
wrote:
 On Tuesday, 21 February 2012 at 14:53:06 UTC, Robert Rouse 
 wrote:
 Using a mixin, is it possible to have it define a method based 
 on a string passed into the mixin?

A simpler way: mixin template MakeMethod(string name) { void _MakeMethod_method() { /* ... */ } mixin("alias _MakeMethod_method " ~ name ~ ";"); }

Feb 21 2012
prev sibling next sibling parent " Adam D. Ruppe" <destructionator gmail.com> writes:
On Tuesday, 21 February 2012 at 18:07:34 UTC, Robert Rouse wrote:
 What am I missing?

Did you remember to new the class? class MyClass {} MyClass a; // a is null right now a = new MyClass(); // gotta remember this That's different than structs (or classes in C++) which work without being new'd.
Feb 21 2012
prev sibling next sibling parent "Robert Rouse" <robert.e.rouse gmail.com> writes:
I did not.

Trying to new it gives me a compile error since "MyClass a" is 
not a pointer.

If I define another method without mixin and call it before the 
"mixin" one, it works.


On Tuesday, 21 February 2012 at 18:13:30 UTC, Adam D. Ruppe wrote:
 On Tuesday, 21 February 2012 at 18:07:34 UTC, Robert Rouse 
 wrote:
 What am I missing?

Did you remember to new the class? class MyClass {} MyClass a; // a is null right now a = new MyClass(); // gotta remember this That's different than structs (or classes in C++) which work without being new'd.

Feb 21 2012
prev sibling parent "Robert Rouse" <robert.e.rouse gmail.com> writes:
Nevermind.. I had it as struct playing around and didn't change 
it back

On Tuesday, 21 February 2012 at 18:37:02 UTC, Robert Rouse wrote:
 I did not.

 Trying to new it gives me a compile error since "MyClass a" is 
 not a pointer.

 If I define another method without mixin and call it before the 
 "mixin" one, it works.


 On Tuesday, 21 February 2012 at 18:13:30 UTC, Adam D. Ruppe 
 wrote:
 On Tuesday, 21 February 2012 at 18:07:34 UTC, Robert Rouse 
 wrote:
 What am I missing?

Did you remember to new the class? class MyClass {} MyClass a; // a is null right now a = new MyClass(); // gotta remember this That's different than structs (or classes in C++) which work without being new'd.


Feb 21 2012