[Home] [Downloads] [Search] [Help/forum]

Gammon Software Solutions forum

See www.mushclient.com/spam for dealing with forum spam. Please read the MUSHclient FAQ!

[Folder]  Entire forum
-> [Folder]  MUSHclient
. -> [Folder]  Python
. . -> [Subject]  How to invoke a class method from trigger?

Home  |  Users  |  Search  |  FAQ
Username:
Register forum user name
Password:
Forgotten password?

How to invoke a class method from trigger?

[Reply to this subject]  Reply to this subject   [New subject]  Start a new subject   [Refresh] Refresh page


Posted by Cadari   (25 posts)  [Biography] bio
Date Tue 08 Jul 2008 07:53 PM (UTC)  quote  ]
Message
Hello. How would you call a class method from a trigger?

class MyClass:
    def __init__(self):
        pass
    def trigger_procedure(self, name, line, wildcards):
        world.Note('Trigger fired.')
        
obj = MyClass()

<triggers>
  <trigger
   enabled="y"
   match="^$"
   regexp="y"
   script="obj.trigger_procedure"
   sequence="100"
  >
  </trigger>
</triggers>

The code above will yield an error "procedure not found". I can register my method in globals...

globals()['obj.trigger_procedure'] = obj.trigger_procedure

...and it will work, but that's just unacceptable. Any way to solve this? Thank you.
[Go to top] top

Posted by Worstje   Netherlands  (867 posts)  [Biography] bio
Date Reply #1 on Tue 08 Jul 2008 10:40 PM (UTC)  quote  ]
Message
I don't think it is possible.

MUSHclient looks for a function 'obj.trigger_procedure' in the global namespace, which doesn't exist. What you want is that MUSHclient queries the trigger_procedure from the 'obj' object, tells Python to call it with Python-regulations (self first), and then to tack on the rest of the parameters.

Maybe you could workaround this with a combination of annotations and importing the functions of your classes into the global namespace, but in annotated form. I know this sounds a bit vague, as I'm not sure how to go about it, but it should technically be possible. I think, anyhow.
[Go to top] top

Posted by Cadari   (25 posts)  [Biography] bio
Date Reply #2 on Fri 11 Jul 2008 11:12 AM (UTC)  quote  ]

Amended on Fri 11 Jul 2008 11:19 AM (UTC) by Cadari

Message
Seems I have to use the ugly approach of doing things this way:

ids = []

class MyClass:
    def __init__(self, name):
        ids.append(id(self))
        self.name = name
    def trigger_procedure(self, name, line, wildcards):
        world.Note('Trigger fired.')
        
myobj = MyClass('myobj')

gc.collect()

for obj in gc.get_objects():
    if id(obj) in ids:
        method_name, method_obj = inspect.getmembers(obj, inspect.ismethod)[1:][0]
        globals()['%s.%s' % (obj.name, method_name)] = method_obj

Or a bit less ugly:

obj_names = []

class MyClass:
    def __init__(self, name):
        self.name = name
        obj_names.append(name)
    def trigger_procedure(self, name, line, wildcards):
        world.Note('Trigger fired.')
        
myobj = MyClass('myobj')

for obj_name in obj_names:
    exec('method_name, method_obj = inspect.getmembers(%s, inspect.ismethod)[1:][0]' % obj_name)
    globals()['%s.%s' % (obj_name, method_name)] = method_obj

At least until I find another way.
[Go to top] top

Posted by Worstje   Netherlands  (867 posts)  [Biography] bio
Date Reply #3 on Sat 12 Jul 2008 04:22 PM (UTC)  quote  ]
Message
Rather than bruteforcing exec in the way you are, I think you should be able to do the same thing with getattr()? I'm only looking at your code briefly and not fully understanding the details of it (not too familliar with the inspect module) but exec() is plain nasty imho.
[Go to top] top

Posted by Cadari   (25 posts)  [Biography] bio
Date Reply #4 on Sat 12 Jul 2008 05:43 PM (UTC)  quote  ]
Message
The exec version is ugly, I agree. As is the whole approach. But I always thought that there's no way to get an object by its name without exec() or eval(), no?

It can be done storing objects themselves, not their names:

objs = []

class MyClass:
    def __init__(self, name):
        self.name = name
        objs.append(self)
    ...
        
myobj = MyClass('myobj')

for obj in objs:
    method_name, method_obj = inspect.getmembers(obj, inspect.ismethod)[1:][0]
    globals()['%s.%s' % (obj.name, method_name)] = method_obj

But, as I said, I don't like any of these versions.
[Go to top] top

The dates and times for posts above are shown in Universal Co-ordinated Time (UTC).

To show them in your local time you can join the forum, and then set the 'time correction' field in your profile to the number of hours difference between your location and UTC time.


2,335 views.

[Reply to this subject]  Reply to this subject   [New subject]  Start a new subject   [Refresh] Refresh page

Go to topic:           Search the forum


[Go to top] top

[Home]

Written by Nick Gammon - 5K

Comments to: Gammon Software support
[RH click to get RSS URL] Forum RSS feed ( http://www.gammon.com.au/rss/forum.xml )

[Best viewed with any browser - 2K]    [Internet Contents Rating Association (ICRA) - 2K]    [Web site powered by FutureQuest.Net]