1

私はWWW::MechanizeWeb ベースのバック オフィスのクリックを自動化するために取り組んでいます テスト e コマース注文を必要な状態にするために行う必要がある 長い複数の部分からなる注文の特定の部分に加えた変更をテストするために必要ですワークフロー。大量の注文をまとめて処理するには、Homeリンクを頻繁にクリックする必要があります。それを短くするために、実行時に次のようにメソッドをハックしました( brian d foy によるMastering PerlWWW::Mechanizeの例に基づいています):

{ # Shortcut to go back to the home page by calling $mech->go_home
  # I know I'll get a warning and do not want it!
  no warnings 'once';
  my $homeLink = $mech->find_link( text => 'Home' )->url_abs();
  $homeLink =~ s/system=0/system=1/;
  *WWW::Mechanize::go_home = sub {
    my ($self) = @_;
    return $self->get($homeLink);
  };
}

これはうまく機能し、私が使用しているスクリプトは私だけが使用し、より大きなシステムの一部ではないため、誰にも害はありません.

$mechしかし、実際には、このメソッドを持つ1 つのオブジェクトのみを伝え、後で作成される可能性のある別のオブジェクトを伝えることができるかどうか疑問に思いWWW::Mechanizeます (たとえば、アクティブなセッションを持つ他のオブジェクトを混同せずに相互参照を行うため)。私のバックオフィス)はその方法を使用できません。

Perl でオブジェクトが動作する方法を理解していれば、オペレーターはパッケージ内->のサブルーチンを探して最初の引数として渡すように指示するため、それが可能かどうかはまったくわかりません。この理解が間違っている場合は修正してください。go_homeWWW::Mechanize$mech

$mech元のオブジェクトのみが関数を使用できるようにする、一種のハードコーディングされたチェックを追加して実験しました。

my $onlyThisMechMayAccessThisMethod = "$mech";
my $homeLink = $mech->find_link( text => 'Home' )->url_abs();
$homeLink =~ s/system=0/system=1/;
*WWW::Mechanize::go_home = sub {
  my ($self) = @_;
  return undef unless $self eq $onlyThisMechMayAccessThisMethod;
  return $self->get($homeLink);
};

"$mech"データが格納されている場所のアドレス (例: ) が含まれているためWWW::Mechanize=HASH(0x2fa25e8)、この方法で文字列化すると、別のオブジェクトの外観が異なります。

しかし、これが進むべき道であるとは確信していません。私の質問は次のとおりです。クラスの1つのオブジェクトだけにこのメソッドを持たせるより良い方法はありますか? WWW::Mechanizeこのコードに関する他の提案もうれしいです。

4

1 に答える 1

5

これだけ

$mech->follow_link(text => 'Home')

また、独自のメソッドを保証したり、オブジェクトの排他的なクラブに制限する必要があるほど特別ではないと思います。

別のパッケージでサブルーチンを宣言するために型グロブをいじる必要がないことも注目に値します。たとえば、書くだけです

sub WWW::Mechanize::go_home {
    my ($self) = @_;
    return $self->get($homeLink);
};

しかし、一般的な解決策はWWW::Mechanize、新しいメソッドが必要なオブジェクトのみをサブクラス化し、メンバーとして宣言することです。


ファイルMyMechanize.pm

package MyMechanize;

use strict;
use warnings;

use parent 'WWW::Mechanize';

sub go_home {
  my $self = shift;
  my $homeLink = $self->find_link(text => 'Home')->url_abs;
  $homeLink =~ s/system=0/system=1/;
  return $self->get($homeLink);
}

1;

ファイルtest.pl

use strict;
use warnings;

use MyMechanize;

my $mech = MyMechanize->new;
$mech->get('http://mydomain.com/path/to/site/page.html')
$mech->go_home;
于 2012-07-24T17:36:05.387 に答える