Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation

Comment on

( #3333=superdoc: print w/replies, xml ) Need Help??

Oh wise and all-knowing gurus...

I am writing a module using Moose that will serve as a wrapper to Net::SSH2 to log into an appliance, grab system information, and return it back to the caller for system monitoring purposes.

My issue is around references. In my module, references aren't working as I would expect them to. I have created a simplified version of the module that replicates the issue to include here.

Here is the code, below. However, please look at lines 125-126 and 131-134 (in the execute() method). If I use the code as pasted here, everything works both hunky and dory. It returns the output of the command run on the appliance as expected. However, if I uncomment lines 125,131-132 and comment out lines 126,133-134, it fails, usually telling me that line 133 is not a GLOB reference. What am I doing wrong?


package Foo; use v5.14; use strict; use warnings; use Carp; use Moose; use MooseX::StrictConstructor; use Net::SSH2; has 'hostname' => ( isa => 'Str', is => 'rw', ); has 'username' => ( isa => 'Str', is => 'rw', ); has 'password' => ( isa => 'Str', is => 'rw', ); has 'command' => ( isa => 'Str', is => 'rw', ); has '_ssh2_connection' => ( is => 'bare', isa => 'Object', ); has '_ssh2_channel' => ( is => 'bare', isa => 'Object', ); ## # Connect to server using provided parameters. # sub connect { my $self = shift; ## # Net::SSH2 connection object. # my $connection = Net::SSH2->new(); # Connect to server. $connection->connect($self->hostname()) or croak "Unable to connect to " . $self->hostname() . ": +$@\n"; $connection->auth_password($self->username(),$self->password()) or croak "Unable to authenticate to " . $self->hostname() . " as " . $self->username . ": $@\n"; ## # Net::SSH2::Channel object. # my $channel = $connection->channel(); # Open Net::SSH2::Channel shell so that multiple commands # can be executed. $channel->blocking(0); $channel->shell(); # Manually flush channel. Uncertain why this must be done, but # when used in an object wrapper, execute() will fail later if # it is not. using $channel->flush() doesn't do the trick. print $channel "\n"; while (<$channel>) { chomp; push my @tmp,"$_\n"; } # Attach connection and channel to object. $self->{_ssh2_channel} = \$channel; $self->{_ssh2_connection} = \$connection; return 1; } ## # Disconnect from server. # sub disconnect { my $self = shift; # Close Net::SSH2 objects. ${$self->{_ssh2_channel}}->close() if (defined ${$self->{_ssh2_cha +nnel}}); ${$self->{_ssh2_connection}}->disconnect() if (defined ${$self->{_ +ssh2_connection}}); # Delete Net::SSH2 objects. $self->{_ssh2_channel} = undef; $self->{_ssh2_connection} = undef; return 1; } ## # Execute command specified by 'command' attribute. # sub execute { # Initialize variables. my $self = shift; #my $channel = ${$self->{_ssh2_channel}}; my $channel = $self->{_ssh2_channel}; my @return_data; my $cmd = $self->command(); # Execute command and process return data. #print $channel "$cmd\n"; #while (<$channel>) { print {${$channel}} "$cmd\n"; while (<${$channel}>) { chomp; push @return_data,"$_\n"; } # Return array ref to caller. return \@return_data; } 1; # End of module. __PACKAGE__->meta->make_immutable; __END__

...and here is a test file, if you'd like to use it...

use v5.14; use strict; use warnings; use Foo; # Define object parameters. use constant { HOSTNAME => '', USERNAME => 'username', PASSWORD => 'password', COMMAND => 'ls -la', }; # Create the object. my $rt = Foo->new({ hostname => HOSTNAME, username => USERNAME, password => PASSWORD, command => COMMAND, }); # Connect to server and execute. $rt->connect(); my $rv = $rt->execute(); $rt->disconnect(); # Print the results. print "$_" foreach (@{$rv}); print "*** DONE ***\n";

In reply to Question regarding using references with Net::SSH2 in module by DarthBobToo

Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":

  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.
  • Log In?

    What's my password?
    Create A New User
    and all is quiet...

    How do I use this? | Other CB clients
    Other Users?
    Others meditating upon the Monastery: (2)
    As of 2018-05-23 01:58 GMT
    Find Nodes?
      Voting Booth?