• 締切済み

use baseしたpackageのローカル変数の書き換え

packageを継承した場合、 継承先(以下のMyPkg)で継承もと(MyBase)のローカル変数($localValue)を直接書き換える方法はありませんか? package MyBase; my $localValue; sub doBase{ my $self=shift; $localValue ={ 'hanako'=>{'id'=>1, 'pref'=>'tokyo'} }; } sub getPref { my $self=shift; my $name=shift; $localValue->{$name}{'pref'}; } package MyPkg; use base qw(MyBase); sub new{ my $class=shift; my $self={}; bless $self, $class; return $self; } sub doAnything { # この中でMyBaseの$localValueを直接書き換えたい $localValue ={ 'taro'=>{'id'=>2, 'pref'=>'osaka'} }; } ------main:: my $pkg=new MyPkg; $pkg->doSomething; print $pkg->getPref('hanako'); $pkg->doAnything; print $pkg->getPref('taro'); ---------- 以下のような感じでmyBaseの中に$localValueを返すサブルーチンを作っておけば、 print $pkg->localValue->{'hanako'}{'pref'}; などと取得は出来ますが、 $pkg->localValue->{'hanako'}{'pref'}='kyoto'; のような代入は無理みたいでした。 package MyBase; my $localValue; sub localValue{ my $self=shift; $localValue; } doBaseのようなサブルーチン経由で書き換えていますが、 use baseしていても、やはりそうしないとダメでしょうか。 Windows、ActivePerl、perl 5.10.0 Linux、Perl5.8

  • Perl
  • 回答数1
  • ありがとう数2

みんなの回答

回答No.1

my $localValueの所をour $localValueとし、doAnything内で$MyBase::localValueのようすればその変数に直接アクセスできます。 ourはパッケージ変数を宣言するものです。 パッケージ変数については参考URLをどうぞ。 http://www.google.co.jp/search?hl=ja&q=perl+%83p%83b%83P%81[%83W%95%CF%90%94&lr=lang_ja http://d.hatena.ne.jp/perlcodesample/20080308/1204953841

taloo
質問者

お礼

ありがとうございます。 sub doBaseじゃなくて、sub doSomethingの書き間違いです。 BBS投稿時に書き換え漏れたようで。。。m(_ _)m やっぱりourですか、、、、 http://perldoc.perl.org/functions/our.html ここのサンプルを読んでourにしてみたのですが、 print $pkg->getPref('hanako'); これで何も出力されずでした。 このページのサンプル > package Foo; > our $bar; > $bar = 20; > > package Bar; > print $bar; をそのまま試しても何も出力されずで、よくわからない状態です。 ourを使うという方向で、試してみます。

taloo
質問者

補足

うまくourが機能してないというか、 package間で共有できていないようですが、あいかわらずよくわかっていません。。。 とりあえず閉めさせていただきます。

関連するQ&A

  • use strictを宣言してlocal変数を使うには?

    Perl初心者です。初歩的な質問ですが、 サブルーチンの中で my だと、その下の{ } ブロックではmyで宣言したローカル変数がスコープされないので  localを使うのではないかと思いますが、 それだと、use strictではエラーになります。 こんなときどう処理したらよいのでしょうか。

    • ベストアンサー
    • Perl
  • Perlで use strict して our変数

    Perl 初心者です。初めて質問します。 test_sub.pl で宣言した変数を test_main.pl から参照したくて悩んでいます。 環境 : WindowsXP / ActivePerl 5.14.2 -------------------- * test_sub.pl -------------------- #!/usr/bin/perl use strict; our $hoge = 'HOGE'; 1; -------------------- * test_main.pl -------------------- #!/usr/bin/perl use strict; require 'test_sub.pl'; print "Content-type: text/html\n\n"; print $hoge; -------------------- これを実行すると、 Global symbol "$hoge" requires explicit package name at C:/public_html/cgi-bin/test_main.pl line 7.\r というエラーが出ます。 require する前に、test_main.pl のほうで our($hoge); と宣言したり 参照する際に print $main::hoge; とパッケージを指定したりすればいけるのですが、 これらをしないとできないものなのでしょうか。 use strict; を書かなければ最初のソースでも動くのですが use strict は書きたい… 継承のようなことをしたいのです。 ちなみに以下試してみたソースです。 -------------------- * test_main.pl -------------------- #!/usr/bin/perl ######################################## # NG use strict; require 'test_sub.pl'; print "Content-type: text/html\n\n"; print $hoge; ######################################## # OK our変数を宣言しておくといける =pod use strict; our ($hoge); require 'test_sub.pl'; print "Content-type: text/html\n\n"; print $hoge; =cut ######################################## # OK 参照する際にパッケージ名を指定すればいける =pod use strict; require 'test_sub.pl'; print "Content-type: text/html\n\n"; print $main::hoge; =cut ######################################## ######################################## # NG =pod use strict; use base qw(test_sub); print "Content-type: text/html\n\n"; print $hoge; =cut ######################################## -------------------- * test_sub.pm -------------------- #!/usr/bin/perl package test_sub; use strict; our $hoge = 'HOGE'; 1; -------------------- NG パタンはどちらも Global symbol "$hoge" requires explicit package name のエラーとなります。 もしご存じの方がいらっしゃいましたら教えてください。 よろしくお願いします。

    • ベストアンサー
    • Perl
  • モジュールのコンストラクタとスコープ

    perlのモジュールを使用する際のコンストラクタで {  package TEST;  new {   my $pkg = shift ;   my @arr1 = (1,2,3,4,5,6) ;   my $self = {    member => "hoge",    arr => \@arr1   }   bless $self,$pkg;  }  sub dref {   $self = shift ;   print @{$self->{arr}};  } } 上記のようにコンストラクタ内でmy指定した@arr1のリファレンスをインスタンスに与えた場合、同package内でデリファレンスできました。($obj->drefを実行した場合配列の中身が表示された) この場合、スコープはどのようになっているのでしょうか。 ( 1.値が保証される 2.参照できるが値を保証しない 3.表示できたのは偶然で、本当は致命的なエラー )

    • ベストアンサー
    • Perl
  • Perlの変数宣言について

    PHPを毎日書いている者ですが、たまたまPerlのメールフォームをカスタマイズ しなければならなくなりました。 use strict宣言がある場合、変数はmyまたはlocalで宣言しなければいけないようですが、 サブルーチン内に sub form { ・・・ my ($form_value,$error_list) = @_; ・・・ print $error_list{'inquiry_type1'} としたところ、 Global symbol "%error_list" requires explicit package name at ・・・ と、宣言が無い場合に出るというエラーが出ました。 $error_listには、inquiry_type1は入っているはずなのですが、どのような 宣言をすればよいのでしょうか? よろしくお願いします。

    • ベストアンサー
    • Perl
  • パッケージ内のグローバル変数

    perlでいまいち理解できないことがあります。 パッケージ内にグローバル変数を作った場合、 外部のスクリプトから完全修飾名で参照できますが、 myによるグローバル変数だけ見ることができません。 レキシカルスコープとはいえ、パッケージ内では グローバル変数にしても参照できないようです。 package MyGlobalVal use vars qw($val1); # これは外部から見える our $val2; #これも外部から見える my $val3; # これは見えない この場合、$val3は外部からなんらかの方法でアクセス 可能なんでしょうか? また参照できない理由はmy宣言により、パッケージの 名前空間とは別の場所(Cだとローカル変数はスタック上に 積まれますよね)にあるから、という理解でよいのでしょうか? アドバイスなどいただけると幸いです。

    • ベストアンサー
    • Perl
  • オブジェクト指向プログラミング

    Perlのクラス定義の例題なんですが、わからないところがあります。 ファイルCapFile.pm package CapFile; sub new{ my $class = shift; my $path = shift; return(bless { ':path' => $path }, $class); } sub read { my $obj = shift; my $path = $obj->{':path'}; ..... ファイルcap-test #!/usr/bin/perl use CapFile; $cap = new CapFile ('/etc/termcap'); $cap->read(); ... サブルーチンreadにある my $path = $obj->{':path'}; なんですが、呼び出し側では引数がないのですが、$objには何が入っているんでしょうか。 そして$pathには何が入るんでしょうか。

    • ベストアンサー
    • Perl
  • perl use strict; と ファイルハンドルについて

    perl use strict; を使うと、単純なエラーが防げると認識していますが、下記スクリプトでは役に立たなかったようで、このエラーを探すのに苦労しました。 他にも、どこかのサブルーチンでsortを使ったスクリプト中で、$aを使った時もおかしな挙動をしたことがあります。 use strict;の使い方は正しいと思うのですが、エラーを出してはくれないものでしょうか? また、このようなエラーをしないために安全なプログラムの書き方はありますか? use strict; open(F,"<file.txt"); while(<F>){ &abc($_); } close(F); sub abc(){ my $str = shift @_; open(F,">>file2.txt"); print F $str; close(F); }

    • ベストアンサー
    • Perl
  • 配列内定義サブルーチン呼び出し

    下記のような配列内定義サブルーチン呼び出しを作成し動作を確認しました。 次にソース2行目の「no strict;」を「use script;」に変更すると Bareword "sub1" not allowed while "strict subs" in use at refsub_OK.pl line 4. Bareword "sub2" not allowed while "strict subs" in use at refsub_OK.pl line 4. Bareword "sub3" not allowed while "strict subs" in use at refsub_OK.pl line 4. Execution of refsub_OK.pl aborted due to compilation errors. とエラーになります。 プログラムはやはり「use script;」を記述したいのですが、「use script;」を記述 したままでエラーにならない方法がありましたらおしえてください。 perlのバージョンは5.12.3、OSはWindowsXP SP3です。 よろしくお願いします。 ---ソースここから--- #!perl no strict; use warnings; my @ary = ( ("input1.txt", "save1.txt", sub1), ("input2.txt", "save2.txt", sub2), ("input3.txt", "save3.txt", sub3), ); while (@ary) { my $p1 = shift(@ary); my $p2 = shift(@ary); my $sub = shift(@ary); print "p1=[$p1] p2=[$p2] sub=[$sub]\n"; &$sub("$p1", "$p2"); } sub sub1 { my ($p1, $p2) = @_; print "sub1: [$p1] [$p2]\n"; } sub sub2 { my ($p1, $p2) = @_; print "sub2: [$p1] [$p2]\n"; } sub sub3 { my ($p1, $p2) = @_; print "sub3: [$p1] [$p2]\n"; } ---ソースここまで---

    • ベストアンサー
    • Perl
  • printが使えなくて困ってます(初心者)

    初心者です。的外れなことを書いていたらすいません。 Template-Toolkitを使った関係でprintが使えなくなるということはありえますでしょうか? ソースすべてはお見せできないので、大まかに書きます。 #! /usr/bin/perl my $luck = new Luck::Mini $luck->execute; package Luck::Mini use Template; sub new {  my $class = shift;  # 省略 } sub excute {  #  eval { subroutin_1() };  # } sub template {  # Templateを使ったサブルーチン } sub subroutin_1 {  #  $rslt = sunroutin_2( );  #  # template に渡す$paramsを生成(パラメータ)  template( abc.html, $params ) # テンプレートを生成して終了 } sub subroutin_2 {  #  for ( my $n = 0; $n < 2; $n ++ ) {   #  }  my $result = [];  # $result にデータを代入する作業  #  return $result; } subroutin_2内で行われいるループの回数$n をprintしたり、 $result をprintしたりしたいと思っています。 現在やっとクラスの考え方が分かり始めたレベルですので、お手柔らかにお願いします。

    • ベストアンサー
    • Perl
  • CGIファイルの書き換えについてです。

    とあるCGIに.pmというファイルが御座います。 そちらの中身に<a href="http://">リンクです</a>を追加したいのですが、上記のタグはどのような形になるか知りたいです。 .pmというソースの開始は package Normal; ;# normal.pm use strict; sub new{ my ($sys,$form) = @_; my $self = { 以下省略 print "$no:\[$skin{'name'}\]<br>"; print "削除されました。<hr>"; } } print "<div align=\"right\">この部分にリンクを追加したいです。</div></body></html>"; } 1; __END__ <a href="http://">テスト</a>という普通のHTMLソースではうまくいかないため、どなたかご教授いただければ幸いでございます。 どうかよろしくお願いいたします

    • ベストアンサー
    • PHP

専門家に質問してみよう