Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW
 
PerlMonks  

...unblessed reference...

by programmer.perl (Beadle)
on Jul 16, 2012 at 17:17 UTC ( [id://982047]=perlquestion: print w/replies, xml ) Need Help??

programmer.perl has asked for the wisdom of the Perl Monks concerning the following question:

Hi everyone,

My script is giving an error message:

Can't call method "set" on unblessed reference at ./oop-closures-objects line 9.

I can't find the reason, @INC is updated, the name of a module is Student.pm. It seems maybe the problem in a variable $access_type? But I can't find the answer, I'll be happy in any kind of a help-messages :-)

Code of package is:

package Student; sub new { # Constructor my $class = shift; my $data={}; our $students; my $ref = sub { # Closure my ($access_type, $key, $value) = @_; if ($access_type eq "set") { $data->{$key} = $value; # $data still available here } elsif ($access_type eq "get") { return $data->{$key}; } elsif ($access_type eq "keys") { return (keys %{$data}); } elsif ($access_type eq "destroy") { $students--; return $students; } else { die "Access type should be set or get"; } print "New student created, we have ", ++$students, " students.\n"; bless ($ref, $class); # bless anonymous subroutine } } # End constructor sub set { my ($self, $key, $value) = @_; # $self reference anonymous sub $self->("set", $key, $value); } sub get { my ($self, $key) = @_; return $self->("get", $key); } sub display { my $self = shift; my @keys = $self->("keys"); @keys=reverse(@keys); foreach my $key (@keys) { my $value = $self->("get", $key); printf "%-25s%-5s:%-20s\n", $self, $key, $value; } print "\n"; } sub DESTROY { my $self = shift; print "Object going out of scope:\n"; print "Students remain: ", $self->("destroy"), "\n"; } 1;

Code of a program that uses the Student.pm:

#!/usr/bin/perl -w use lib("lib"); use Student; $ptr1 = Student->new(); # Create new students $ptr2 = Student->new(); $ptr3 = Student->new(); $ptr1->set("Name", "Jody Rogers"); # Set data for object $ptr1->set("Major", "Law"); $ptr2->set("Name", "Christian Dobbins"); $ptr2->set("Major", "Drama"); $ptr3->set("Name", "Tina Savage"); $ptr3->set("Major", "Art"); $ptr1->display(); # Get all data for object $ptr2->display(); $ptr3->display(); print "\nThe major for ", $ptr1->get("Name"), " is ", $ptr1->get("Major"), ".\n\n";

Replies are listed 'Best First'.
Re: ...unblessed reference...
by BrowserUk (Patriarch) on Jul 16, 2012 at 17:29 UTC

    If you add strict & warnings to the top of your module, perl will tell you why.


    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.

    The start of some sanity?

Re: ...unblessed reference...
by jdporter (Paladin) on Jul 16, 2012 at 18:06 UTC

    er, I think you want that bless call outside the anonymous sub! And don't forget that the assignment my $ref = sub {...} is a statement, so you'll need a semicolon after it. (You got away with it before because it was the last statement in the enclosing block.)

Re: ...unblessed reference...
by CountZero (Bishop) on Jul 16, 2012 at 19:39 UTC
    You should also put your print "New student created, we have ", ++$students, " students.\n"; outside of the anonymous subroutine. The way it is done now, you increase the number of students with each set-method called upon a Student object.

    It is the first time I see an object constructor that returns a blessed code reference. I really wonder what special benefit this has over the more usual blessed hash. Care to enlighten me?

    CountZero

    A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

    My blog: Imperial Deltronics

      Data encapsulation/privacy. It means no calling code can snoop on the object's data by doing $obj->{'member'}.

        I have always found this encapsulation / privacy thing vastly overrated. If people want to snoop inside your objects (and discover the data they themselves previously put inside the object) and possibly mess up everything, then it is their responsibility, isn't it?

        CountZero

        A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

        My blog: Imperial Deltronics

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://982047]
Approved by BrowserUk
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others imbibing at the Monastery: (5)
As of 2024-04-23 16:46 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found