princepawn has asked for the wisdom of the Perl Monks concerning the following question:

Here is the module in which can() isnt working for me:
package Games::Grid; require 5.005_62; use strict; use warnings; use Term::Cap; require POSIX; require Exporter; our @ISA = qw(Exporter); # Items to export into callers namespace by default. Note: do not expo +rt # names by default without a very good reason. Use EXPORT_OK instead. # Do not simply export all your public functions/methods/constants. # This allows declaration use Games::Grid ':all'; # If you do not need this, moving things directly into @EXPORT or @EXP +ORT_OK # will save memory. our %EXPORT_TAGS = ( 'all' => [ qw( ) ] ); our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); our @EXPORT = qw( ); our $VERSION = '0.01'; sub top { $_[0]->{border} }; sub left { $_[0]->{border} }; sub clear_screen { $_[0]->{terminal}->Tgoto('cl', 0, 0, $_[0]->{FH}); } sub make_grid { my $self = shift; my $w = $self->can("right"); my $b = $self->can("bottom"); my $s = $self->can("scream"); warn "w,b,s: $w, $b, $s"; my ($border,$width,$height) = $self->{border}, $self->$w(), $self->$b(); warn " ($border,$width,$height) "; my $FH = $self->{FH}; my $terminal = $self->{terminal}; my $grid = $self->{grid}; for my $x ($border..$width-$border) { for my $y ($border..$height-$border) { $terminal->Tgoto('cm', $x, $y, $FH); print $grid; } } } sub new { my $class = shift; my %config = @_; my $self = { border => $config{border}, fill => $config{fill} }; { my $termios = new POSIX::Termios; $termios->getattr; my $ospeed = $termios->getospeed; $self->{terminal} = Tgetent Term::Cap { TERM => undef, OSPEED => $ +ospeed }; # require certain capabilities to be available $self->{terminal}->Trequire(qw/ce ku kd/); $self->{terminal}->{width} = $self->{terminal}->{_co}; $self->{terminal}->{height} = $self->{terminal}->{_li}; $self->{effective}{width} = $self->{terminal}->{width} - $self-> +{border}; $self->{effective}{height} = $self->{terminal}->{height} - $self-> +{border}; *{bottom} = $config{bottom}; *{Games::Grid::right} = $config{right}; } # Output Routines, if $FH is undefined these just return the string $self->{FH} = \*STDOUT; select(STDOUT); ++$|; bless $self, $class; } 1; __END__
And here is how I call it:
use Games::Grid; my $g = Games::Grid->new (border => 4, right => sub { $_[0]->{effective}{width} }, bottom => sub { $_[0]->{effective}{height} }, fill => '='); # $g->clear_screen; warn sprintf "T: %d B: %d L: %d R: %d", $g->top, $g->bottom, $g->left, $g->right; my $b = $g->can("bottom"); my $r = $g->can("right"); warn sprintf "r: $r, b: $b... %d, %d", $g->$b(), $g->$r(); $g->make_grid;
And as the output shows, the can() method works fine in the calling test script, but within the make_grid() method of Games::Grid, the same usage of can() does not return the expected data.
PERL_DL_NONLAZY=1 /arudev/bin/perl -Iblib/arch -Iblib/lib -I/arudev/li +b/perl5/5.6.0/sun4-solaris -I/arudev/lib/perl5/5.6.0 test.pl 1..1 ok 1 T: 4 B: 20 L: 4 R: 76 at test.pl line 29. r: CODE(0x174768), b: CODE(0x18f480)... 20, 76 at test.pl line 35. Use of uninitialized value in concatenation (.) at blib/lib/Games/Grid +.pm line 49. w,b,s: CODE(0x174768), CODE(0x18f480), at blib/lib/Games/Grid.pm line + 49. Use of uninitialized value in concatenation (.) at blib/lib/Games/Grid +.pm line 56. Use of uninitialized value in concatenation (.) at blib/lib/Games/Grid +.pm line 56. (4,,) at blib/lib/Games/Grid.pm line 56. Use of uninitialized value in subtraction (-) at blib/lib/Games/Grid.p +m line 61. {ap555sun:tmbranno:tmbranno_1674066_sql_memory_hogging:arupatch}115> / +home/tmbranno/src/Games/Grid %

Edit: chipmunk 2001-03-07

Replies are listed 'Best First'.
Re: I need help calling can()
by btrott (Parson) on Mar 08, 2001 at 05:06 UTC
    Your problem is nothing to do with can.

    Ack, updated: chromatic has told me correctly that you can call code refs just like princepawn is doing. Which invalidates my first point, leaving me only with...

    Your problem is how you're setting your variables in make_grid. You have:

    my ($border,$width,$height) = $self->{border}, $self->$w(), $self->$b();
    You need parens around the right side. So it should look like this:
    my($border,$width,$height) = ($self->{border}, $w->($self), $b->($self));
    And that fixes the problem, or so it would seem, since when running the code my terminal cursor gets repositioned (very annoyingly, I might add :).
Re: I need help calling can()
by InfiniteSilence (Curate) on Mar 08, 2001 at 18:51 UTC
    I have a slightly related question: Why do people post their entire module? Aren't they debugging, in which case they would have the problem isolated to a few functions/lines of code?

    Celebrate Intellectual Diversity

      if a small test case can reproduce the problem, it is ideal.

      if one is not sure where the problem is, indiscriminately cutting things out might cut out what was causing the problem.

        if one is not sure where the problem is, indiscriminately cutting things out might cut out what was causing the problem

        ...and there-by give you a clue as to the source of the problem, perhaps allowing you to solve the problem yourself. Which is why it is polite to do this before you come asking for help on a problem. It also greatly increases the odds of you getting a quick and accurate answer.

                - tye (but my friends call me "Tye")