To bless or not to bless, this is my question!

first post from a new user. It seems that every question I ask Google brings me here, and I always get a great answer to what I'm looking for; so naturally, this was my first stop when I started thinking about using blessings in Perl.

I just got into Perl OOP and just today read a message about what the blessing is doing. Now I understand that it refers to the scalar / hash / array array on the object, "sticking" it if you want.

In most examples of classes that I see in Perl, they don't seem to have properties, as I'm used to seeing in other languages ​​...

{ package Person; my $property = "This is what I'm talking about :)"; sub new { ... } ... } 

So, I created a stupid class with a property to find out what will happen. I gave the property the value "NIL" right off the bat, and then "Don't Neil!" in the constructor. Using the LIST method, I was able to print the property, and, as I expected, it printed "Not Nil!"

My question is: if properties work just as I expected them to work (declared in the body), then why use the blessing at all? What additional benefit does this link have when you could just create a scalar / hash / array as a property, or create any links you want as a property?

I hope I explained that I'm trying to ask quite well, very green with Perl :)

+6
oop class perl bless
source share
4 answers

Well, that’s not how you create classes in Perl.

Your $property variable is defined in the package area. Therefore, for each class there will be only one copy, and not every object that has its own copy.

You can implement such a class using hash objects in a long and difficult way, as shown below:

 #!/usr/bin/perl package Person; use strict; use warnings; sub new { my $class = shift; my $self = {}; bless $self => $class; my ($arg) = @_; for my $property ( qw( message ) ) { if ( exists $arg->{$property} ) { $self->$property($arg->{$property}); } } return $self; } sub message { my $self = shift; return $self->{message} unless @_; my ($msg) = @_; $self->{message} = $msg; } package main; my $person = Person->new({ message => "This is what I'm talking about :)" }); print $person->message, "\n"; 

Now it is tiresomely fast. So, there are modules that will help you deal with this, as well as help you define your classes so that they are safe for inheritance.

Class :: Accessor is one such module.

For programs in which startup time is not a problem, you should consider Moose . With Moose you can write above:

 #!/usr/bin/perl package Person; use Moose; has 'message' => (is => 'rw', isa => 'Str'); __PACKAGE__->meta->make_immutable; no Moose; package main; my $person = Person->new({ message => "This is what I'm talking about :)" }); print $person->message, "\n"; 

You should read perldoc perltoot and Moose :: Manual :: Unsweetened for a standard way of doing things.

+11
source share

What you did with $ property in this case is declared a variable in the scope of the Person package. You change this inside (or outside using the $ Person: :) property of the package, and any object that refers to it will see the updated variable, so it acts like a "static attribute (Java)" without any real "private" region. By convention, hidden things in Perl ("private" or "protected") have an underscore prefix, but of course this does not apply.

In fact, you are not creating a new class, as you indicated, with the keyword "package"; You can use the "package" without OOP. It just creates a separate "namespace".

The advantage of the “blessing” of a variable, almost always the hash links from what I saw, is that you can have methods like any other OOP language. Just remember to bless everything that you return in the new {} subroutine (the “new” is not really a reserved word, but just an agreement). When you call a method on an “object” (a blissful data structure such as hashref), the first argument to the method is the data structure itself. So, if you have a hashref called $ myobject that is blessed by AwesomeClass, and you define a method in AwesomeClass called doSomethingAwesome that should take one variable, you will have to "shift" @_ (this is a list of arguments to the routine or use $ _ [0 ]) to access $ myobject hashref. Python does something similar, and all languages ​​somehow pass an object reference to a method. ("this" is a keyword in many, see also the calling convention "thiscall")

NB: I saw a lot of bugs in Perl that were just a few years a programmer. Perl is an amazing language that was made by a very clever linguist (Larry Wall) and has a fanatical follow-up - more fanatical at one time than Ruby, perhaps, but not as much as David Koresh). Perl does things differently than many languages, but if you look at the golf records on this site and others, you can clearly see that a lot can be achieved with a very small Perl (no guarantees of code clarity, especially for beginners!)

+8
source share

The bless ' value of an object is to use methods from a specific package.

 package MyClass; sub answer { my ($self) =@ _; return $self->{foo} * 42; } package main; my $object1 = { foo => 1, bar => "\t" }; my $object2 = bless { foo => 2, bar => "\t" }, "MyClass"; $ref1 = ref $object1; # 'HASH' $ref2 = ref $object2; # 'MyClass' $answer1 = $object1->answer; # run time error $answer2 = $object2->answer; # calls MyClass::answer, returns 2 * 42 = 84 
+5
source share

Uh ... The answer to Sinan is completely too studied to my taste, at least in the last 12 hours :)

So, I will give a shorter and slightly smaller Perly, just for the sake of variety.

Your question is not entirely about Perl , as far as I can tell, and can be just as easily considered in another form: "Why use C ++ and OOP in it when C already has structures?"

In other words, you seem to be wondering what the use of the OOP paradigm means.

The answer, of course, helps solve some software development problems, rather than purely procedural programming. Focus on certain - OOP is not a panacea for every problem, nothing more than ANY method / approach / paradigm.

Using OOP (in the form of packages as classes and blissful hashes as objects in Perl) allows you to take advantage of inheritance, polymorphism and other OOPyish mumbo-jumbo, which you are probably already quite familiar with. You are not Perl OOP Experience.

Can you do 100% of what you would do with a blessed object with a clean data structure? Absolutely. Will 100% of this code be simple and short / readable / supported as you can achieve using objects? Most likely not, although it depends on how well your OOP code actually takes advantage of the benefits that OOP provides (BTW, I have , which supposedly have OOP code (Perl and not), which actually had no advantage OOP and it might have been easier to read and understand if it had been deprived of its OOP chromium).

+4
source share

All Articles