Passing object from subroutine problem

Discussion in 'Perl Misc' started by tim, Sep 27, 2006.

  1. tim

    tim Guest

    Hello

    I'm new here, so, hi!

    I've been having the following problem. I have a module which I am
    creating to manage sessions for my website. I have the following sub in
    it:

    #takes an active db handle, returns a new session object.
    sub newSession {
    my $dbh = @_[1];
    my %session;
    tie %session, 'Apache::Session::MySQL', undef,
    { Handle => $dbh,
    LockHandle => $dbh};
    print "Session session ref = ". \%session . "\n";
    return \%session;
    }

    In the calling routine, I have the following code:

    my $sessionref = SessionManager->newSession($dbh);
    my %session = %$sessionref;
    tied(%session)->delete;

    The first two lines seem to work ok, but the 3rd gives this error:

    Can't call method "delete" on an undefined value at ./tester line 31.

    Bizarely, it seems I can access the object in other ways from the same
    context, as the following lines work as expected:

    print "session id = $session{_session_id}\n";
    print "testing session ref = " . $sessionref . "\n";

    (i.e. session id is printed)

    I'd really appreciate any comments or suggestions on why the above may
    be occuring.

    Many thanks

    Tim.
     
    tim, Sep 27, 2006
    #1
    1. Advertising

  2. tim

    Paul Lalli Guest

    tim wrote:

    > I'm new here, so, hi!


    Welcome! Please make sure you read the Posting Guidelines for this
    group (posted here twice a week) to learn valuable tips to maximize the
    potential usefulness of posting here...

    > I've been having the following problem. I have a module which I am
    > creating to manage sessions for my website. I have the following sub in
    > it:
    >
    > #takes an active db handle, returns a new session object.
    > sub newSession {
    > my $dbh = @_[1];


    Always always always use warnings when devleoping Perl code. This
    should have told you:
    Scalar value @_[1] better written as $_[1]

    > my %session;
    > tie %session, 'Apache::Session::MySQL', undef,
    > { Handle => $dbh,
    > LockHandle => $dbh};
    > print "Session session ref = ". \%session . "\n";
    > return \%session;
    > }
    >
    > In the calling routine, I have the following code:
    >
    > my $sessionref = SessionManager->newSession($dbh);
    > my %session = %$sessionref;


    %session is a brand new hash, simply populated with the values that are
    currently in the variable %$sessionref. It is in all other ways
    unrelated to $sessionref. It is not tied to any object of the
    Apache::Session::MySQL class.

    > tied(%session)->delete;
    >
    > The first two lines seem to work ok, but the 3rd gives this error:
    >
    > Can't call method "delete" on an undefined value at ./tester line 31.


    Because %session is not a tied variable, tied() returns undef.

    >
    > Bizarely, it seems I can access the object in other ways from the same
    > context, as the following lines work as expected:
    >
    > print "session id = $session{_session_id}\n";


    _session_id is one of the keys you copied over when you created the new
    hash, so yes, that works.

    > print "testing session ref = " . $sessionref . "\n";
    >
    > (i.e. session id is printed)


    $sessionref is a reference to the original tied variable, so yes, that
    works.

    > I'd really appreciate any comments or suggestions on why the above may
    > be occuring.


    Copying a hash does not copy the tied nature of the variable.

    Paul Lalli
     
    Paul Lalli, Sep 27, 2006
    #2
    1. Advertising

  3. tim

    tim Guest

    Thanks Paul

    Whoops- didn't notice that warnings were off. I'll make sure they're on
    before posting next time!!

    Tim

    Paul Lalli wrote:
    > tim wrote:
    >
    > > I'm new here, so, hi!

    >
    > Welcome! Please make sure you read the Posting Guidelines for this
    > group (posted here twice a week) to learn valuable tips to maximize the
    > potential usefulness of posting here...
    >
    > > I've been having the following problem. I have a module which I am
    > > creating to manage sessions for my website. I have the following sub in
    > > it:
    > >
    > > #takes an active db handle, returns a new session object.
    > > sub newSession {
    > > my $dbh = @_[1];

    >
    > Always always always use warnings when devleoping Perl code. This
    > should have told you:
    > Scalar value @_[1] better written as $_[1]
    >
    > > my %session;
    > > tie %session, 'Apache::Session::MySQL', undef,
    > > { Handle => $dbh,
    > > LockHandle => $dbh};
    > > print "Session session ref = ". \%session . "\n";
    > > return \%session;
    > > }
    > >
    > > In the calling routine, I have the following code:
    > >
    > > my $sessionref = SessionManager->newSession($dbh);
    > > my %session = %$sessionref;

    >
    > %session is a brand new hash, simply populated with the values that are
    > currently in the variable %$sessionref. It is in all other ways
    > unrelated to $sessionref. It is not tied to any object of the
    > Apache::Session::MySQL class.
    >
    > > tied(%session)->delete;
    > >
    > > The first two lines seem to work ok, but the 3rd gives this error:
    > >
    > > Can't call method "delete" on an undefined value at ./tester line 31.

    >
    > Because %session is not a tied variable, tied() returns undef.
    >
    > >
    > > Bizarely, it seems I can access the object in other ways from the same
    > > context, as the following lines work as expected:
    > >
    > > print "session id = $session{_session_id}\n";

    >
    > _session_id is one of the keys you copied over when you created the new
    > hash, so yes, that works.
    >
    > > print "testing session ref = " . $sessionref . "\n";
    > >
    > > (i.e. session id is printed)

    >
    > $sessionref is a reference to the original tied variable, so yes, that
    > works.
    >
    > > I'd really appreciate any comments or suggestions on why the above may
    > > be occuring.

    >
    > Copying a hash does not copy the tied nature of the variable.
    >
    > Paul Lalli
     
    tim, Sep 27, 2006
    #3
  4. Paul Lalli <> wrote:
    > tim wrote:


    >> #takes an active db handle, returns a new session object.
    >> sub newSession {
    >> my $dbh = @_[1];

    >
    > Always always always use warnings when devleoping Perl code. This
    > should have told you:
    > Scalar value @_[1] better written as $_[1]



    And that accesses the 2nd argument. What about the 1st argument?

    my $dbh = $_[0];

    but a much better way to handle subroutine arguments is:

    my($dbh) = @_; # don't forget the parenthesis

    That makes it very easy to add an additional argument:

    my($dbh, $max_value) = @_;


    --
    Tad McClellan SGML consulting
    Perl programming
    Fort Worth, Texas
     
    Tad McClellan, Sep 27, 2006
    #4
  5. tim

    Mirco Wahab Guest

    Thus spoke tim (on 2006-09-27 14:08):

    > I'm new here, so, hi!


    Great!

    > #takes an active db handle, returns a new session object.
    > sub newSession {
    > my $dbh = @_[1];


    Shouldn't the @_[1], which is
    a array slice containing the
    *second* argument of the caller,
    read: $_[0] ... ?

    > my $sessionref = SessionManager->newSession($dbh);
    > my %session = %$sessionref;
    > tied(%session)->delete;


    Here you drop a single argument to your function ...

    (The return will be a ref to empty hash or sth.)

    Regards

    Mirco
     
    Mirco Wahab, Sep 27, 2006
    #5
  6. tim

    Paul Lalli Guest

    Mirco Wahab wrote:
    > Thus spoke tim (on 2006-09-27 14:08):
    >
    > > I'm new here, so, hi!

    >
    > Great!
    >
    > > #takes an active db handle, returns a new session object.
    > > sub newSession {
    > > my $dbh = @_[1];

    >
    > Shouldn't the @_[1], which is
    > a array slice containing the
    > *second* argument of the caller,
    > read: $_[0] ... ?


    No. Please take a few moments to learn about method calls in Perl:
    perldoc perlmod

    > > my $sessionref = SessionManager->newSession($dbh);
    > > my %session = %$sessionref;
    > > tied(%session)->delete;

    >
    > Here you drop a single argument to your function ...


    Yes, but Perl passed an additional first argument - the object itself.

    Paul Lalli
     
    Paul Lalli, Sep 27, 2006
    #6
  7. tim

    Mirco Wahab Guest

    Thus spoke Paul Lalli (on 2006-09-27 15:02):
    > Mirco Wahab wrote:
    >> Thus spoke tim (on 2006-09-27 14:08):
    >> > #takes an active db handle, returns a new session object.
    >> > sub newSession {
    >> > my $dbh = @_[1];

    >>
    >> Shouldn't the @_[1], which is
    >> a array slice containing the
    >> *second* argument of the caller,
    >> read: $_[0] ... ?

    >
    > No. Please take a few moments to learn about method calls in Perl:
    > perldoc perlmod


    Uhmm, you are correct, he actually used
    object call syntax, sorry.

    >> Here you drop a single argument to your function ...

    >
    > Yes, but Perl passed an additional first argument - the object itself.


    About time for me to get used to "Perl Objects", I guess.

    Thanks & Regards

    Mirco
     
    Mirco Wahab, Sep 27, 2006
    #7
  8. tim

    Paul Lalli Guest

    Tad McClellan wrote:
    > Paul Lalli <> wrote:
    > > tim wrote:

    >
    > >> #takes an active db handle, returns a new session object.
    > >> sub newSession {
    > >> my $dbh = @_[1];

    > >
    > > Always always always use warnings when devleoping Perl code. This
    > > should have told you:
    > > Scalar value @_[1] better written as $_[1]

    >
    >
    > And that accesses the 2nd argument. What about the 1st argument?
    >
    > my $dbh = $_[0];


    newSession is a class method, so the first argument is the name of the
    class. The argument that the user passed into the method is indeed the
    2nd argument within the method.

    Paul Lalli
     
    Paul Lalli, Sep 27, 2006
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    6
    Views:
    2,761
    Eric Bohlman
    Apr 4, 2005
  2. Mark Drummond

    Passing a list as an arg to a subroutine

    Mark Drummond, Mar 7, 2006, in forum: Perl
    Replies:
    2
    Views:
    2,308
    Thomas Wasell
    Mar 9, 2006
  3. Replies:
    2
    Views:
    630
  4. Ben Bullock

    Problem with passing array to subroutine

    Ben Bullock, May 25, 2006, in forum: Perl Misc
    Replies:
    11
    Views:
    147
    Tad McClellan
    May 26, 2006
  5. king
    Replies:
    5
    Views:
    188
Loading...

Share This Page