Loading ...
Sorry, an error occurred while loading the content.

How to traverse just by using reference

Expand Messages
  • saurabh talwar
    Hi My problem is that I have reference to another reference (p4_info has reference to another reference) and that other reference could be a hash or an array.
    Message 1 of 9 , Jan 5, 2009
    • 0 Attachment
      Hi

      My problem is that I have reference to another reference (p4_info has
      reference to another reference) and that other reference could be a hash or
      an array. I tried all the techniques but no luck.

      I want to be able to advance one byte and then print out what the value is
      and then again advance another byte, check to see which reference is it
      (hash, or array or scalar) and then dereference that.

      I am sorry to bother you guys, I am sending you the output if that helps.

      sub run_info()
      {
      my $key;
      my $value;
      my $p4_info;
      my $val;
      $p4_info = $p4->Run( "info" );
      print ("\n p4_info is $p4_info \n");
      *for (@{$p4_info})
      {
      print $_, "\n";
      }*

      OUTPUT
      =====
      *p4_info is ARRAY(0x2270b4)
      HASH(0x1830a58) *


      [Non-text portions of this message have been removed]
    • James E Keenan
      ... I don t understand what you mean by advance one byte. Do you mean you want to iterate through the elements of the array referenced by $p4_info? Would
      Message 2 of 9 , Jan 5, 2009
      • 0 Attachment
        On Jan 5, 2009, at 8:16 PM, saurabh talwar wrote:
        >
        >
        > I want to be able to advance one byte and then print out what the
        > value is
        > and then again advance another byte, check to see which reference
        > is it
        > (hash, or array or scalar) and then dereference that.


        I don't understand what you mean by "advance one byte." Do you mean
        you want to iterate through the elements of the array referenced by
        $p4_info?

        Would simply dumping the contents of $p4_info suffice?

        use strict;
        use warnings;
        use Data::Dumper;

        my $p4_info = [
        { alpha => 'beta', gamma => 'delta' },
        [ qw( red blue green ) ],
        { dog => 'canine', cat => 'feline' },
        'string',
        345,
        ];

        print Dumper $p4_info;
      • saurabh talwar
        Hi James I am not sure if the next character is another reference or a character which could be displayed on the screen. I am sure what i am reading is an
        Message 3 of 9 , Jan 5, 2009
        • 0 Attachment
          Hi James

          I am not sure if the next character is another reference or a character
          which could be displayed
          on the screen. I am sure what i am reading is an array of hashes.

          Therefore, how will i traverse an array of hashes when I am not sure what is
          in it.

          I was not sure how to traverse by reference and at each character use the
          ref () function to determine
          what kind of reference is it pointing to.

          I hope I clarified your doubt.

          Regards.
          Sunny

          On Mon, Jan 5, 2009 at 6:25 PM, James E Keenan <jkeen@...> wrote:

          >
          > On Jan 5, 2009, at 8:16 PM, saurabh talwar wrote:
          > >
          > >
          > > I want to be able to advance one byte and then print out what the
          > > value is
          > > and then again advance another byte, check to see which reference
          > > is it
          > > (hash, or array or scalar) and then dereference that.
          >
          > I don't understand what you mean by "advance one byte." Do you mean
          > you want to iterate through the elements of the array referenced by
          > $p4_info?
          >
          > Would simply dumping the contents of $p4_info suffice?
          >
          > use strict;
          > use warnings;
          > use Data::Dumper;
          >
          > my $p4_info = [
          > { alpha => 'beta', gamma => 'delta' },
          > [ qw( red blue green ) ],
          > { dog => 'canine', cat => 'feline' },
          > 'string',
          > 345,
          > ];
          >
          > print Dumper $p4_info;
          >
          >
          >


          [Non-text portions of this message have been removed]
        • Mike Allred
          You could probably save a lot of effort doing something like... use Data::Dumper; print Dumper $p4_info; ... [Non-text portions of this message have been
          Message 4 of 9 , Jan 5, 2009
          • 0 Attachment
            You could probably save a lot of effort doing something like...

            use Data::Dumper;
            print Dumper $p4_info;

            On Mon, Jan 5, 2009 at 8:16 PM, saurabh talwar <talwar.saurabh@...>wrote:

            > Hi
            >
            > My problem is that I have reference to another reference (p4_info has
            > reference to another reference) and that other reference could be a hash or
            > an array. I tried all the techniques but no luck.
            >
            > I want to be able to advance one byte and then print out what the value is
            > and then again advance another byte, check to see which reference is it
            > (hash, or array or scalar) and then dereference that.
            >
            > I am sorry to bother you guys, I am sending you the output if that helps.
            >
            > sub run_info()
            > {
            > my $key;
            > my $value;
            > my $p4_info;
            > my $val;
            > $p4_info = $p4->Run( "info" );
            > print ("\n p4_info is $p4_info \n");
            > *for (@{$p4_info})
            > {
            > print $_, "\n";
            > }*
            >
            > OUTPUT
            > =====
            > *p4_info is ARRAY(0x2270b4)
            > HASH(0x1830a58) *
            >
            > [Non-text portions of this message have been removed]
            >
            >
            >


            [Non-text portions of this message have been removed]
          • James E Keenan
            ... Pseudo-code: for my $el ( @{ $p4_info } ) { if ( not ref $el ) { # it s not a reference, therefore it s a scalar print $el n ; } else { # it is a
            Message 5 of 9 , Jan 5, 2009
            • 0 Attachment
              On Jan 5, 2009, at 9:31 PM, saurabh talwar wrote:

              >
              > I was not sure how to traverse by reference and at each character
              > use the
              > ref () function to determine
              > what kind of reference is it pointing to.
              >
              >

              Pseudo-code:

              for my $el ( @{ $p4_info } ) {
              if ( not ref $el ) {
              # it's not a reference, therefore it's a scalar
              print "$el\n";
              } else {
              # it is a reference
              # What you do with it depends on the type of reference
              # and on the needs of your project
              # see: perldoc -f ref
              # for all the data types which can be referenced
              }
              }
            • Steven Lembark
              ... It is difficult -- at best -- to iterate the contents by byte . If you simply want to SEE the contents then just use Data::Dumper to serialize the thing:
              Message 6 of 9 , Jan 6, 2009
              • 0 Attachment
                > My problem is that I have reference to another reference (p4_info has
                > reference to another reference) and that other reference could be a hash or
                > an array. I tried all the techniques but no luck.
                >
                > I want to be able to advance one byte and then print out what the value is
                > and then again advance another byte, check to see which reference is it
                > (hash, or array or scalar) and then dereference that.
                >
                > I am sorry to bother you guys, I am sending you the output if that helps.

                It is difficult -- at best -- to iterate the contents
                by "byte". If you simply want to SEE the contents then
                just use Data::Dumper to serialize the thing:


                use Data::Dumper;

                sub pretty_struct
                {
                local $Data::Dumper::Purity = 1;
                local $Data::Dumper::Terse = 1;
                local $Data::Dumper::Indent = 1;
                local $Data::Dumper::Deepcopy = 0;
                local $Data::Dumper::Quotekeys = 0;

                local $\ = "\n";
                local $, = "\n";

                print map { ref $_ ? Dumper $_ : $_ } @_
                }


                my $struct = sub_that_returns_the_structure_from_hell;

                pretty_struct 'The structure from hell is:', $struct;


                To walk down the structure use Scalar::Util's reftype
                (avoids issues with objects) and re-dispatch each one
                based on the reftype.

                use Scalar::Util qw( reftype );

                my $tabs = 0;

                my %handlerz =
                (
                '' => sub { print "\t" x $tabs, @_, "\n" },
                hash => '',
                array => '',
                scalar => '',
                );

                sub walk
                {
                my $handler = $handlerz{ reftype $_[0] }
                or croak "Unhandled type $_[0]";

                goto &$handler;
                }

                sub walk_hash
                {
                my $ref = shift;

                local $tabs = $tabs + 1;

                for ( sort keys %$ref )
                {
                print "\t" x $tabs, $_ . ' => ', "\n";

                walk $ref->{ $_ };
                }
                }

                sub walk_array
                {
                my $ref = shift;

                local $tabs = $tabs + 1;

                for( 0 .. $#$ref )
                {
                print "\t" x $tabs, $_, ' = ', "\n";
                walk $ref->[ $_ ];
                }
                }

                sub walk_scalar
                {
                my $ref = shift;

                local $tabs = $tabs + 1;

                print "\t" x $tabs, $$ref;
                }

                # build this after the sub's exist.

                while( my( $k, $v ) = each %handlerz )
                {
                $v ||= __PACKAGE__->can( "walk_$k" );
                }

                You can increment a tab level to get indentation at
                each walk_foo via local $tabs = $tabs + 1 and
                then use ( "\t" x $tabs ) to indent the output.

                That or snag the guts of Data::Dumper and put your own
                handlers into it (vs. just printing them).

                --
                Steven Lembark 85-09 90th St.
                Workhorse Computing Woodhaven, NY, 11421
                lembark@... +1 888 359 3508
              • saurabh talwar
                Thanks a lot Steven ! Thats a long code. I guess I will use the tip you have given me below. I will need to bother you again if I face any issues. Regards.
                Message 7 of 9 , Jan 6, 2009
                • 0 Attachment
                  Thanks a lot Steven !

                  Thats a long code. I guess I will use the tip you have given me below.

                  I will need to bother you again if I face any issues.

                  Regards.
                  Saurabh

                  On Tue, Jan 6, 2009 at 9:27 AM, Steven Lembark <lembark@...> wrote:

                  >
                  > > My problem is that I have reference to another reference (p4_info has
                  > > reference to another reference) and that other reference could be a hash
                  > or
                  > > an array. I tried all the techniques but no luck.
                  > >
                  > > I want to be able to advance one byte and then print out what the value
                  > is
                  > > and then again advance another byte, check to see which reference is it
                  > > (hash, or array or scalar) and then dereference that.
                  > >
                  > > I am sorry to bother you guys, I am sending you the output if that helps.
                  >
                  > It is difficult -- at best -- to iterate the contents
                  > by "byte". If you simply want to SEE the contents then
                  > just use Data::Dumper to serialize the thing:
                  >
                  > use Data::Dumper;
                  >
                  > sub pretty_struct
                  > {
                  > local $Data::Dumper::Purity = 1;
                  > local $Data::Dumper::Terse = 1;
                  > local $Data::Dumper::Indent = 1;
                  > local $Data::Dumper::Deepcopy = 0;
                  > local $Data::Dumper::Quotekeys = 0;
                  >
                  > local $\ = "\n";
                  > local $, = "\n";
                  >
                  > print map { ref $_ ? Dumper $_ : $_ } @_
                  > }
                  >
                  > my $struct = sub_that_returns_the_structure_from_hell;
                  >
                  > pretty_struct 'The structure from hell is:', $struct;
                  >
                  > To walk down the structure use Scalar::Util's reftype
                  > (avoids issues with objects) and re-dispatch each one
                  > based on the reftype.
                  >
                  > use Scalar::Util qw( reftype );
                  >
                  > my $tabs = 0;
                  >
                  > my %handlerz =
                  > (
                  > '' => sub { print "\t" x $tabs, @_, "\n" },
                  > hash => '',
                  > array => '',
                  > scalar => '',
                  > );
                  >
                  > sub walk
                  > {
                  > my $handler = $handlerz{ reftype $_[0] }
                  > or croak "Unhandled type $_[0]";
                  >
                  > goto &$handler;
                  > }
                  >
                  > sub walk_hash
                  > {
                  > my $ref = shift;
                  >
                  > local $tabs = $tabs + 1;
                  >
                  > for ( sort keys %$ref )
                  > {
                  > print "\t" x $tabs, $_ . ' => ', "\n";
                  >
                  > walk $ref->{ $_ };
                  > }
                  > }
                  >
                  > sub walk_array
                  > {
                  > my $ref = shift;
                  >
                  > local $tabs = $tabs + 1;
                  >
                  > for( 0 .. $#$ref )
                  > {
                  > print "\t" x $tabs, $_, ' = ', "\n";
                  > walk $ref->[ $_ ];
                  > }
                  > }
                  >
                  > sub walk_scalar
                  > {
                  > my $ref = shift;
                  >
                  > local $tabs = $tabs + 1;
                  >
                  > print "\t" x $tabs, $$ref;
                  > }
                  >
                  > # build this after the sub's exist.
                  >
                  > while( my( $k, $v ) = each %handlerz )
                  > {
                  > $v ||= __PACKAGE__->can( "walk_$k" );
                  > }
                  >
                  > You can increment a tab level to get indentation at
                  > each walk_foo via local $tabs = $tabs + 1 and
                  > then use ( "\t" x $tabs ) to indent the output.
                  >
                  > That or snag the guts of Data::Dumper and put your own
                  > handlers into it (vs. just printing them).
                  >
                  > --
                  > Steven Lembark 85-09 90th St.
                  > Workhorse Computing Woodhaven, NY, 11421
                  > lembark@... <lembark%40wrkhors.com> +1 888 359 3508
                  >
                  >
                  >


                  [Non-text portions of this message have been removed]
                • saurabh talwar
                  Thanks James for the help. I think I might be able to resolve this issue now. Regards. Sunny ... [Non-text portions of this message have been removed]
                  Message 8 of 9 , Jan 6, 2009
                  • 0 Attachment
                    Thanks James for the help.

                    I think I might be able to resolve this issue now.

                    Regards.
                    Sunny

                    On Mon, Jan 5, 2009 at 7:36 PM, James E Keenan <jkeen@...> wrote:

                    >
                    > On Jan 5, 2009, at 9:31 PM, saurabh talwar wrote:
                    >
                    > >
                    > > I was not sure how to traverse by reference and at each character
                    > > use the
                    > > ref () function to determine
                    > > what kind of reference is it pointing to.
                    > >
                    > >
                    >
                    > Pseudo-code:
                    >
                    > for my $el ( @{ $p4_info } ) {
                    > if ( not ref $el ) {
                    > # it's not a reference, therefore it's a scalar
                    > print "$el\n";
                    > } else {
                    > # it is a reference
                    > # What you do with it depends on the type of reference
                    > # and on the needs of your project
                    > # see: perldoc -f ref
                    > # for all the data types which can be referenced
                    > }
                    > }
                    >
                    >
                    >


                    [Non-text portions of this message have been removed]
                  • Steven Lembark
                    ... Note: for this kind of thing you are better off using Scalar::Util::reftype. The difference is that if part of the structure is blessed, reftype will still
                    Message 9 of 9 , Jan 7, 2009
                    • 0 Attachment
                      >> > ref () function to determine

                      Note: for this kind of thing you are better off
                      using Scalar::Util::reftype. The difference is
                      that if part of the structure is blessed, reftype
                      will still give you ARRAY, etc, rather than a
                      package name.


                      --
                      Steven Lembark 85-09 90th St.
                      Workhorse Computing Woodhaven, NY, 11421
                      lembark@... +1 888 359 3508
                    Your message has been successfully submitted and would be delivered to recipients shortly.