![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?8acaa2e)
Perl初心者です。双方向に値を取り出せる TwoWayMapクラスを作成し、以下の期待値を取得したいのですが、エラーが出てうまく実行できません。原因について、アドバイスをお願いいたします。
(エラーメッセージ)
Can't locate object method "new" via package "TwoWayMap" at samplev2-2.pl line 6.
(期待値)
Apfel
apple
pear
---- TwoWayMap class :ファイル名 samplev2.pl ----------------
package TwoWayMap;
$forward_hash={};
$reverse_hash={};
sub put{
$forward_hash{$_[0]}=$_[1];
$reverse_hash{$_[1]}=$_[0];
}
sub get{
return $forward_hash{$_[0]};
}
sub rev{
return $reverse_hash{$_[0]};
}
---- main ファイル名:samplev2-2.pl------------------------
package main;
use TwoWayMap;
our $e2g = new TwoWayMap;
$e2g->put('apple', 'Apfel');
$e2g->put('pear', 'Birne');
print $e2g->get('apple'), "\n";
print $e2g->rev('Apfel'), "\n";
print $e2g->rev('Birne'), "\n";
No.3ベストアンサー
- 回答日時:
示された samplev2-2.pl 中には、どこにも「samplev2.pl」の読み込み指示がありません。
修正したsamplev2.pl が読み込まれてないだけでしょう。「use TwoWayMap」した場合、TwoWayMap.pm が読み込まれます。
代わりに「require 'samplev2-2.pl'」としてみてください。
あるいは、とりあえず動作を確認しただけなら、samplev2-2.pl の中に
samplev2.pl の内容をそのまま埋め込んでもいいでしょう。
> ●あと、各メソッド内のforward_hash,reverse_hashなどを$_[0]->として引数から呼び出しているのはなぜでしょうか?
元のコードのままだと、newしたクラスオブジェクトとは無関係に、全体で forward_hash・ reverse_hashを共有することになっていまします。
クラス設計としては、「TwoWayMapクラスのオブジェクト」毎に、二つの連想記憶配列を保持する必要があります。
「クラスオブジェクト」自体は一つの変数ですから、ここに二つの連想記憶配列を保持するために、「連想記憶配列の連想記憶配列」という多段の連想記憶配列として実現してるわけです。
初期化をもうちょっと真面目にやるなら
> sub new {
> my %data;
> $data{forward_hash} = {};
> $data{reverse_hash} = {};
> return bless \%data;
> }
って感じ。
ここで、bless することで、blessされた変数を介したメソッド呼び出しは、
パッケージ指定が不要になり、また暗黙の第1引数が追加されるようになります。これが perl のオブジェクト指向のキモです。
> $e2g->put('apple', 'Apfel');
は、$e2g が package TwoWayMap 内で bless されたものですので、
> TwoWayMap::put($e2g, 'apple', 'Apfel');
と等価になります。
メソッド put は3引数を受け取り、第1引数の変数内の連想記憶配列に、
第2引数・第3引数で指定されたデータを記録しています。
getやrevは2引数を受け取りますので、第1引数内の連想記憶配列から、第2引数で指定されたデータを読み出します。
No.4
- 回答日時:
> ●ありがとうございます。
いただいたコメントをもとに、> samplev2.plを以下のとおり修正し実行しても、同じエラーが出力さ
> れてしまいます。なぜでしょう?
main側のuseで指定するのはパッケージ名ではなくてファイル名のはず。だから、
package main;
use samplev2;
our $e2g = new TwoWayMap();
としないと、perlはどのファイルがクラス定義をしているのか分からない。
また、クラス定義をする側のファイルの拡張子はplではなく、pmを使うのが普通だったはず。
samplev2.pl → samplev2.pm
No.2
- 回答日時:
このソースでは、名前空間(package名)「TwoWayMap」の下に普通の関数を作っただけで、まったくクラスが作れていません。
クラスの作り方について勉強をやり直してください。キーワードは「bless」でしょうか。
---ここから---
package TwoWayMap;
sub new {
my %data;
return bless \%data;
}
sub put {
$_[0]->{forward_hash}->{$_[1]}=$_[2];
$_[0]->{reverse_hash}->{$_[2]}=$_[1];
}
sub get {
return $_[0]->{forward_hash}->{$_[1]};
}
sub rev {
return $_[0]->{reverse_hash}->{$_[1]};
}
---ここまで---
こんな感じで。
この回答への補足
●ありがとうございます。いただいたコメントをもとに、samplev2.plを以下のとおり修正し実行しても、同じエラーが出力されてしまいます。なぜでしょう?
●あと、各メソッド内のforward_hash,reverse_hashなどを$_[0]->として引数から呼び出しているのはなぜでしょうか?
すみません、いろいろ調べてみてはいるのですが、いまいち理解が進まず質問させていただいております。
(エラー)
Can't locate object method "new" via package "TwoWayMap" at samplev2-2.pl line 6.
(修正後のコード)
#!/usr/bin/perl -w
package TwoWayMap;
sub new {
my %data;
return bless %data;
}
sub put {
$_[0]->{forward_hash}->{$_[1]}=$_[2];
$_[0]->{reverse_hash}->{$_[2]}=$_[1];
}
sub get {
return $_[0]->{forward_hash}->{$_[1]};
}
sub rev {
return $_[0]->{reverse_hash}->{$_[1]};
}
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) エクセルのマクロについて教えてください。 1 2022/10/13 08:41
- Visual Basic(VBA) batからexeを実行し戻り値を受け取る バッチからEXEの結果を受け取りたいのですが、 下記のバッ 1 2023/07/04 15:13
- Visual Basic(VBA) batからexeを実行し戻り値を受け取る EXEの実行内容の結果によって、戻り値を0か1かで返したい 1 2023/07/04 16:40
- その他(プログラミング・Web制作) laravel 本番環境でメールが送れません。 1 2023/02/17 17:57
- オープンソース stable diffusionのインストールがうまくいきません。 1 2023/06/20 13:09
- Excel(エクセル) 表示形式、文字列セル(列)に数式を入力するには マクロ 1 2022/09/18 10:53
- その他(プログラミング・Web制作) pythonのプログラムについての質問です。 1 2023/05/26 10:31
- Excel(エクセル) エクセルの複数条件作成方法について 2 2023/01/23 21:38
- Visual Basic(VBA) Excel VBA カーソルを当てた際に表示される”4161”とは 1 2022/04/30 21:53
- Visual Basic(VBA) エクセルのマクロとシートの保護について教えてください。 1 2022/10/18 08:36
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
INDIRECT 横に再度抽出したい
-
Perlで、「が」を、「...
-
このファイルを開く方法で困っ...
-
perlのflock関数でロックをかけ...
-
perl 正規表現でエラー
-
P.Cのシングルチューナーとダブ...
-
perl LWPでURLにアクセスした時...
-
PerlでUTF-8のファイルの文字列...
-
AI sisterとは、偽物の人ですか?
-
Perlで時間の計算
-
perlのrequireの動き方について...
-
Perlで特定文字列から特定文字...
-
アルファベットに付いて質問し...
-
#!/usr/bin/perlで書きだしたCG...
-
Perlのエラーについてご教授く...
-
bashスクリプト
-
ファイルアイコンの左下に緑の□...
-
perlプログラミング 空白行削除
-
perlでリテラル値はメモリにど...
-
perlで2次元配列をサブルーチ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
if($key){ ($key eq 'aaa') ||...
-
双方向リスト(?)
-
HTML::TemplateのTMPL_LOOPにつ...
-
連番ごとに印をつける
-
変数に何も入ってないとき
-
Perlのリファレンスについて
-
ハッシュを無名変数へ代入して...
-
VB6の公式リファレンスはありま...
-
bashのリファレンス的なWEB...
-
DBIを使用してデータを連想配列...
-
重複する値を表示しない
-
クラスの作り方
-
Perl構造体、出力方法
-
ハッシュの配列を作ることは可...
-
Yahooの掲示板のような掲示板を...
-
ファイルからデータを読み込ん...
-
Perlで縦横変換のような事をし...
-
サブルーチンの返値に配列のハ...
-
構造体の配列の指定方法
-
C言語について。
おすすめ情報