in reply to what is difference between calling the function in Perl/Tk in the following ways

A colleague of mine recomends the first approach. The second one sometimes leads to memory leaks, if the button itself is passed as one of the parameters to the sub.
  • Comment on Re: what is difference between calling the function in Perl/Tk in the following ways

Replies are listed 'Best First'.
Re^2: what is difference between calling the function in Perl/Tk in the following ways
by runrig (Abbot) on Apr 16, 2010 at 00:08 UTC
    I'd expect a memory link from code like:
    my $button; $button = $frame->Button(... , -command => sub { SomeFunction($button) + });
    But it should only matter if the button is created more than once (and I'd only worry about that if it's created many times). On a single-window app where you only create widgets once, it really doesn't matter. If it does matter, then you can probably use Scalar::Util::weaken() to get around it (but by then I'd agree that it's probably easier to use the first method).
Re^2: what is difference between calling the function in Perl/Tk in the following ways
by ikegami (Patriarch) on Apr 16, 2010 at 14:53 UTC
    I don't see how one could leak and not the other. You could always change
    (-command=>sub {&function($arg1,$arg2)});
    to
    (-command=>[sub {&function($arg1,$arg2)}]);
    but I suspect that's already happening internally.
      It's the circular reference preventing garbage collection that would cause the leak. The same sort of leak that happens when you repeatedly create anonymous recursive subs like:
      my $fact; $fact = sub { my $n = shift; return $n if $n <= 1; return $n*fact($n-1); }
      Hmm, you're right, the other one would probably leak also if they both contain $button. (update: oops...looking at wrong thread since the OP didn't even have a circular reference in the example).

        the other one would probably leak also if they both contain $button

        Exactly.

        my $obj; my $obj = { data => [ \&f, \$obj ] }; # leaks my $obj; my $obj = { data => [ sub { f($obj) } ] }; # leaks my $arg; my $obj = { data => [ \&f, \$arg ] }; # doesn't leak my $obj; my $obj = { data => [ sub { f($arg) } ] }; # doesn't leak
      Both these two would leak, I fear. The only safe way is to call
      -command=>[\&function,\$arg1,\$arg2]

        By adding \$arg1,\$arg2, the memory leak goes away? I don't think so.