Calling method by name.

Jacob Carlborg doob at me.com
Fri Feb 4 07:33:51 PST 2011


On 2011-02-04 04:29, Robert Jacques wrote:
> On Thu, 03 Feb 2011 08:49:54 -0500, Jacob Carlborg <doob at me.com> wrote:
>
>> On 2011-02-03 05:52, Robert Jacques wrote:
>>> On Wed, 02 Feb 2011 12:55:37 -0500, %u <fghf at jhgjhb.com> wrote:
>>>
>>>> I know is possible to create an object from its name. It's possible to
>>>> call a method from that object if the name is only known at runtime?
>>>>
>>>> Would something like the following be possible?
>>>>
>>>> string classname, methodname;
>>>> // Ask the user for class and method.
>>>> auto obj = Object.factory(classname);
>>>> invoke(methodname, obj, param1, param2);
>>>>
>>>> Thanks
>>>
>>> I've been working on an update to std.variant, which includes a
>>> compile-time reflection to runtime-reflection system. (See
>>> https://jshare.johnshopkins.edu/rjacque2/public_html/) From the docs:
>>>
>>> Manually registers a class with Variant's runtime-reflection system.
>>> Note that Variant automatically registers any types it is exposed. Note
>>> how in the example below, only Student is manually registered; Grade is
>>> automatically registered by Variant via compile-time reflection of
>>> Student.
>>>
>>> module example;
>>> class Grade { real mark; }
>>> class Student { Grade grade; }
>>> void main(string[] args) {
>>> Variant.__register!Student;
>>> Variant grade = Object.factory("example.Grade");
>>> grade.mark(96.6);
>>> assert(grade.mark == 96.6);
>>> }
>>>
>>> And dynamic method/field calls are handled via the __reflect(string
>>> name, Variant[] args...) method like so:
>>>
>>> grade.__reflect("mark",Variant(96.6));
>>> assert(grade.__reflect("mark") == 96.6);
>>
>> Why would you need to pass in Variants in __reflect? Why not just make
>> it a variadic method and automatically convert to Variant?
>>
>
> Well, opDispatch does exactly that. __reflect, on the other hand, was
> designed as a quasi-backend function primarily for a) internal use
> (hence the double underscore), b) scripting language
> interfacing/implementing and c) user-extension. So efficiency was of key
> importance. And the reflection system is extensible, as Variant knows to
> call __reflect on user defined types. This makes things like prototype
> style objects possible. (There's even a beta implementation of a
> prototype object in the library) But this requires that the use
> __reflect methods not be templated.
>
> I'm not well versed in dynamic reflection and its use cases, so when I
> considered the combination of a runtime method name and compile-time
> argument type information, I classed it as 'rare in practice'. But if
> that's not the case, I'd like to know and would greatly appreciate a use
> case/unit test.

I recommend looking at Ruby, it has very good support for runtime 
reflection. ActiveRecord in Rails is hevaly based on runtime reflection. 
For example, given the following Ruby class:

class Post < ActiveRecord::Base
end

The class "Post" maps to the database table "posts", no configuration is 
necessary. Then you can use the column names in the table as fields to 
set and get data, like this:

post = Post.new
post.title = "some title"
post.body = "the body"
post.save # will update the database

All this is done using runtime reflection. Then you can query the 
database, also using runtime reflection:

Post.find_by_name_and_body("some title", "the body")

Will find the first row where "title" and "body" matches the given values.

-- 
/Jacob Carlborg


More information about the Digitalmars-d mailing list