#32 Broken $::world->trigger() calls (part 2)

open-accepted
None
5
2011-02-27
2011-02-26
Ron Lovis
No

Calls to $::world->trigger() produce a Perl warning whenever you use variables, rather than literal strings, as its arguments.

The trigger is also not created.

The plugin below demonstrates the problem. If any of the three arguments are variables, rather than literal strings, the following warning is produced:

Perl Warning trigger: Wrong argument type at /home/ron/example.pl line 18

Discussion

  • Ron Lovis
    Ron Lovis
    2011-02-26

     
    Attachments
  • The error is not because you are using a variable, but because the variable is undefined - you never attributed a value to it, so you're essentially calling "$world->trigger(undef, undef, { name => 'trigger_2' } )". The error message does not make that very clear, it's true.

    If the variables have values, then it works.

    If you want some dynamic trigger that matches every line against the current value of a variable, that's not possible. You can, however, define a trigger to be run on every line, calling a function that then matches the line against a variable and does whatever you want.

     
    • assigned_to: nobody --> ekalin
    • status: open --> closed-invalid
     
  • Ron Lovis
    Ron Lovis
    2011-02-27

    Hi Eduardo,

    Apologies - I sent you a script which doesn't work, and doesn't even demonstrate the problem.

    Even when the three variables have values, I still get the same warning.

    I have been porting my windows mud client into a KC plugin. Here is the output the plugin produces, when it tries to create a trigger:

    [ Debug: Setting up a trigger ]
    [ Debug: $triggerPattern is set to ]
    [ Debug: pattern ]
    [ Debug: $triggerAction is set to ]
    [ Debug: action ]
    [ Debug: $triggerName is set to ]
    [ Debug: jmud:independent_trigger_1 ]
    [ Debug: Now calling $::world->trigger($triggerPattern, $triggerAction, { name => $triggerName }) ]
    Perl Warning: trigger: Wrong argument type at /home/ra/Local/Code/jmud/interface.pm Line 329.
    [ Debug: Finished setting up the trigger ]

    Here is the Perl code:

    &writeDebug ("Setting up a trigger");
    &writeDebug ('$triggerPattern is set to');
    &writeDebug ($triggerPattern);
    &writeDebug ('$triggerAction is set to');
    &writeDebug ($triggerAction);
    &writeDebug ('$triggerName is set to');
    &writeDebug ($triggerName);
    &writeDebug ('Now calling $::world->trigger($triggerPattern, $triggerAction, { name => $triggerName }) ');

    # Create the trigger
    # This line should work, but doesn't
    $::world->trigger($triggerPattern, $triggerAction, { name => $triggerName });
    # This line does work - even though it uses exactly the same strings!
    # $::world->trigger("pattern", "action" , { name => "jmud:independent_trigger_1" });

    &writeDebug ("Finished setting up the trigger");

     
  • The fragment you posted does not set the variables. Based on the output, it seems they are set elsewhere, but I'll need a complete example to test. Preferably one that contains only the code necessary to exhibit the problem.

    "Wrong argument type" is emitted when an argument to trigger() is neither a string nor a hash reference. Maybe the variables are not really strings, but look like one when converted to strings?

     
    • status: closed-invalid --> pending-accepted
     
  • Ron Lovis
    Ron Lovis
    2011-02-27

    Hi Eduardo,

    I have removed everything that's unnecessary from my plugin. I have also added lots of comments. The result is example3.pl, and it produces the same Perl warning.

    The plugin reacts to the following command:

    //atr -p pattern -a action

    'atr' is short for 'addtrigger', and it must be preceded by two forward slashes

     
  • Ron Lovis
    Ron Lovis
    2011-02-27

     
    Attachments
  • Well, when the trigger is created (in a C function), perl thinks those arguments are not of type scalar, but of blessed scalar. But I don't know why this happens. There seems to be nothing in the code that blesses anything, and what's worse, inspecting the variables from the plugin side shows that they appear to be normal scalars.

    I have no idea what's causing this strange behavior. However, your example is hardly minimal. Perhaps you could try removing more code to ease further investigation.

     
  • Ron Lovis
    Ron Lovis
    2011-02-27

     
    Attachments
  • Ron Lovis
    Ron Lovis
    2011-02-27

    Hi Eduardo,

    Thanks for your responses, and apologies for my long plugins. I had found it impossible to write a shorter script, which demonstrated the problem.

    However, I have now made some progress.

    The Perl warning appears when you:
    (1) Write an alias to capture commands, and redirect them to your plugin
    (2) Separate the command into words with Perl's split() function
    (3) Test one of the words with Perl's substr() function

    Weird, huh? example5.pl demonstrates the problem, and it's only 60 lines long!

    (1) Break the script by commenting out line 34, and uncommenting line 35
    (2) Without reversing these changes, repair the script by commenting out line 40, and uncommenting line 41

    Perhaps you can test example5.pl and let me know, if your C function still thinks that $triggerPattern and $triggerAction are blessed scalars?

     
  • Ron Lovis
    Ron Lovis
    2011-02-27

    • status: pending-accepted --> open-accepted
     
  • Ron Lovis
    Ron Lovis
    2011-02-27

    Addendum:

    The Perl warning appears when you:
    (1) Write an alias to capture commands, and redirect them to your plugin
    (2) Separate the command into words with Perl's split() function
    (3) Test one of the words with Perl's substr() function
    (4) Try to create a trigger, using the words

     
  •  
    Attachments
  • I've been able to further eliminate the split, the same happens by dealing with $inputString directly.

    Summarizing, it's the substr call that somehow "marks" the variable with another type (indeed, blessed scalar, even if it's not even a reference!). See the new real short example. The first call works, the second one after the substr does not, even if the return value is never used for anything. What's worse, further calls will fail even before substr(), even though we should be dealing with a completely different variable.

    (Be aware that running the example creates a trigger never deleted afterwards.)

    If you want a workaround, just use "$triggerPattern" in the call, that creates a new string with the same value, or append an empty string: $triggerPattern.

    As for the reason, I don't know... doesn't look like a problem with KildClient, but more with libperl, but it's hard to say. Perhaps I should try to write a minimal C program that embeds perl and runs that code to see if the same behaviour happens. I'll see.

    Which version of perl are you using? Mine is not the latest, perhaps first I should test with perl 5.12.

     
  • And by the way, this has nothing to do with being an alias (the same problem happens if the function is called directly), being in a plugin (I tested with a simple function in a script file, the same happens) or because $world->trigger() is called (the same happens with other functions, even those not requiring $world to be called).

     
  • Ron Lovis
    Ron Lovis
    2011-02-28

    Hi Eduardo,

    I installed Perl 5.12.3 on my Ubuntu box this morning. The warning messages still appear.

     
  •  
    Attachments
  • I wrote a small test (attached, if anyone is interested) with nothing KildClient-specific, and the problem indeed manifests itself. So the problem, whatever it is, is not in KildClient.

    I discovered, furthermore, that is it caused by using the "encoding 'utf8'" pragma.

    I'm not sure if it's necessary anymore to use that directive. I remember I needed it to solve some problems a long time ago (perl was at 5.6, or perhaps even 5.4). I compiled without it, and did not notice any obvious problem, but I need to make further tests.

    But anyway, something is very strange. I'll try asking in a perl mailing list to see what the experts can say, since it's nothing KC specific.