6

初心者ユーザーからの最初の投稿。私がグーグルで検索するすべての質問は、私をここに連れてきてくれるようで、私が探しているものに対する素晴らしい答えをいつも得ています。当然のことながら、これは、Perl での祝福の使用法について熟考し始めた最初の目的地でした。

Perl の OOP を始めたばかりで、今日、bless が何をするのかを尋ねる投稿を読みました。スカラー/ハッシュ/配列をオブジェクトに参照し、必要に応じて「アタッチ」することを理解しました。

Perl で見られるクラスの例のほとんどでは、他の言語で見慣れているようなプロパティを持っていないようです...

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

    sub new { ... }
    ...
}

そこで、何が起こるかを確認するために、プロパティを持つ愚かなクラスを作成しました。プロパティの値をすぐに「NIL」に設定し、次に「Nil ではありません!」と設定しました。コンストラクターで。メソッド LIST を使用して、プロパティを出力することができました。予想どおり、「Not Nil!」と出力されました。

私の質問は、プロパティが期待どおりに機能する場合 (本体で宣言されている場合)、なぜ bless を使用するのですか? スカラー/ハッシュ/配列をプロパティとして作成したり、必要な参照をプロパティとして作成したりできる場合に、その参照を持つことの追加の利点は何ですか?

私が尋ねようとしていることを十分に説明したいと思います.Perlで非常に環境に優しいです:)

4

4 に答える 4

11

まあ、それは Perl でクラスを作成する方法ではありません。

変数$propertyはパッケージ スコープで定義されます。したがって、各オブジェクトが独自のコピーを持つのではなく、クラスごとにそのコピーが 1 つだけ存在します。

以下のように、ハッシュベースのオブジェクトを使用して、そのようなクラスを長く困難な方法で実装できます。

#!/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";

さて、これはすぐに退屈になります。したがって、これに対処するだけでなく、継承に対して安全な方法でクラスを定義するのに役立つモジュールがあります。

Class::Accessorは、そのようなユーティリティ モジュールの 1 つです。

起動時間が問題にならないプログラムの場合は、Mooseを検討する必要があります。Moose では、上記を次のように記述できます。

#!/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";

標準的な方法については、perldoc perltootMoose::Manual::Unsweetenedを読む必要があります。

于 2010-08-11T04:00:23.323 に答える
8

この場合に $property で行ったことは、「Person」パッケージのスコープで変数として宣言されています。パッケージの内部 (または $Person::property を使用して外部) を変更すると、それを参照するすべてのオブジェクトが更新された変数を参照するため、実際の「プライベート属性」のない「静的属性 (Java)」のように機能します。"スコープ。慣例により、Perl の隠し要素 (「プライベート」または「保護」) にはアンダースコアが前に付けられますが、もちろんこれは強制されません。

ご指摘のとおり、「package」キーワードを使用して実際に新しいクラスを作成することはありません。OOPなしで「パッケージ」を使用できます。それは単に別の「名前空間」を作成するだけです。

変数 (ほとんどの場合、私が見たハッシュ参照) を「祝福」する利点は、他の OOP 言語と同様に、メソッドを使用できることです。new {} サブルーチンで返すものは何でも bless することを忘れないでください (「new」は実際には予約語ではなく、単なる慣例です)。「オブジェクト」(hashref のような祝福されたデータ構造) でメソッドを呼び出す場合、メソッドの最初の引数はデータ構造自体です。したがって、AwesomeClass に祝福された $myobject というハッシュリファレンスがあり、1 つの変数を受け入れる必要がある doSomethingAwesome という名前のメソッドを AwesomeClass で定義する場合、@_ (これはサブルーチン、または $_[0]) を使用して $myobject ハッシュリファレンスにアクセスします。Python は似たようなことをします。そしてすべての言語は、オブジェクト参照を何らかの方法でメソッドに渡します。(多くの「this」キーワード、「thiscall」呼び出し規約も参照)

注意: 私は、プログラマーとして数年しか経っていない私の時代に、Perl のバッシングをたくさん見てきました。Perl は、非常に賢い言語学者 (Larry Wall) によって作成された素晴らしい言語であり、熱狂的な支持者がいます。一時的には Ruby よりも熱狂的かもしれませんが、David Koresh ほどではありません)。Perl は多くの言語とは非常に異なることを行いますが、このサイトや他のサイトのコード ゴルフ エントリを見ると、ごくわずかな Perl で多くのことが達成できることがはっきりとわかります (特に初心者にとって、コードの読みやすさについての保証はありません!)。

于 2010-08-11T03:55:56.653 に答える
5

blessオブジェクトを作成することの価値は、特定のパッケージのメソッドを使用することです。

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
于 2010-08-11T04:44:54.560 に答える
4

うーん...シナンの答えは、少なくとも午前12時を過ぎて、私の好みには完全に学習しすぎています:)

ですから、多様性のために、短くてやや少ない Perly のものを提供します。

あなたの質問は、私が知る限り、実際には Perl に関するものではなく、別の形式でも同じように簡単に説明できます。

言い換えれば、OOP パラダイムを使用するポイントは何かを尋ねているようです。

その答えはもちろん、純粋な手続き型プログラミングよりも簡単に特定のソフトウェア エンジニアリングの問題を解決するのに役立つからです。特定の強調- OOP はすべての問題の万能薬ではありません。任意の手法/アプローチ/パラダイムと同様です。

OOP を (Perl ではクラスとしてのパッケージとオブジェクトとしての祝福されたハッシュの形式で) 使用すると、継承、ポリモーフィズム、および Perl 以外の OOP の経験からおそらくすでにかなり精通している他の OOPy のマンボジャンボの利点を楽しむことができます。

純粋なデータ構造を備えた祝福されたオブジェクトで行うことの 100% を行うことができますか? 絶対。その 100% は、オブジェクトを使用して達成できるのと同じくらい簡単/短く/読みやすく/保守可能なコードでしょうか? おそらくそうではありませんが、OOPコードが実際にOOPが提供する利点をどれだけうまく活用しているかに依存します(ところで、 OOPパラダイムを実際に活用しておらず、作成された可能性あると思われるOOPコード(Perlでなくても)に遭遇しましたOOP クロムを取り除いた方が読みやすく、理解しやすくなります)。

于 2010-08-11T04:19:13.753 に答える