1

Lincoln Stein のNetwork Programming With Perlの一連の IO モジュールを使用しようとしていますが、次のエラーが発生します。

Can't locate object method "blocking" via package "IO::LineBufferedSessionData" 
at /mxhome/charrison/private/perl/IO/SessionData.pm line 22.

この本の Addison/Wesley サイトからダウンロードしたモジュールのコレクションには、blocking() サブルーチンが含まれていません。いくつか掘り下げた後、IO::Socket にあるblocking() サブルーチンを呼び出すことを期待しているという証拠を見つけました。またはIO::File、またはおそらくIO::Handle....そして実際、IO::Handleにはblocking()メソッドがあります。

以下は IO::SessionData モジュールの上部で、barfing している行を含みます:

package IO::SessionData;
# file: IO/SessionData.pm                                                                                                   
# Figure 13.5: The IO::SessionData Module Code                                                                              

use strict;
use Carp;
use IO::SessionSet;
use Errno 'EWOULDBLOCK';
use vars '$VERSION';
$VERSION = 1.00;

use constant BUFSIZE => 3000;

# Class method: new()                                                                                                       
# Create a new IO::SessionData object.  Intended to be called from within                                                   
# IO::SessionSet, not directly.                                                                                             
sub new {
  my $pack = shift;
  my ($sset,$handle,$writeonly) = @_;
  # make the handle nonblocking        
  #######################################################################                                                                                     
  $handle->blocking(0);       # <=== THIS IS THE CALL IT FAILS ON
  #######################################################################
  my $self = bless {
                outbuffer   => '',
                sset        => $sset,
                handle      => $handle,
                write_limit => BUFSIZE,
                writeonly   => $writeonly,
                choker      => undef,
                choked      => undef,
               },$pack;
  $self->readable(1) unless $writeonly;
  return $self;
}

これが問題のトラブルシューティングに十分な情報であるかどうかはわかりません。モジュールやオブジェクト指向 Perl についてはほとんど理解していません。blocking作成者は何らかのスーパークラス (IO::Handle? など) 内でメソッドを呼び出すつもりであると推測しています。この本は 2001 年に書かれたもので、おそらくいくつかのルールが変更されています。または、テキストにバグがある可能性があります。誰かが解決策を提案したり、詳細情報を要求したりできますか?

更新 1:confessこれは、問題のあるblocking() 呼び出しの直前に 生成されたスタック トレースです。

/Users/chap/private/wdi/server$ ./server_template -v
 at /Users/chap/private/wdi/lib/IO/SessionData.pm line 21.
    IO::SessionData::new('IO::LineBufferedSessionData', 'IO::LineBufferedSet=HASH(0x7fcbe19bd450)', 'IO::Socket::INET=GLOB(0x7fcbe18a8070)', undef) called at /Users/chap/private/wdi/lib/IO/LineBufferedSessionData.pm line 21
    IO::LineBufferedSessionData::new('IO::LineBufferedSessionData', 'IO::LineBufferedSet=HASH(0x7fcbe19bd450)', 'IO::Socket::INET=GLOB(0x7fcbe18a8070)', undef) called at /Users/chap/private/wdi/lib/IO/SessionSet.pm line 46
    IO::SessionSet::add('IO::LineBufferedSet=HASH(0x7fcbe19bd450)', 'IO::Socket::INET=GLOB(0x7fcbe18a8070)') called at /Users/chap/private/wdi/lib/IO/SessionSet.pm line 136
    IO::SessionSet::wait('IO::LineBufferedSet=HASH(0x7fcbe19bd450)') called at /Users/chap/private/wdi/lib/IO/LineBufferedSet.pm line 24
    IO::LineBufferedSet::wait('IO::LineBufferedSet=HASH(0x7fcbe19bd450)') called at ./server_template line 221

ご覧のとおり、new() は内部で呼び出されています。(私のアプリケーションはスタックの一番下にあります。それ以外はすべて本からのものです。)

4

1 に答える 1

1

何が起こっているのかというと、クラスには、メソッドを持つクラスに渡される引数(2番目の引数)が必要->blocking()です。次のように呼び出す必要があります。

my $sset = ...;
my $handle = IO::Handle->new( ... ); #  build your IO handle
my $writeonly = ... ; 

my $session_data = IO::SessionData->new($sset, $handle, $writeonly);

最初の行、

my $pack = shift;

クラス名です。これの慣用的な名前は、代わりに次のようになります。

my $class = shift;

この追加の変数はnew、オブジェクト呼び出し構文(構文)を介して呼び出されたときに自動的に追加されます。シフトすることにより、パラメーターリストObject::Name->methodからそのクラス名が削除されます。@_残りの値はコンストラクターへの引数です。2番目の引数が$handle呼び出されてそのメソッドが呼び出されるため、そのメソッドを持つ変数を渡す必要があります。そのメソッドを処理するものなら何でもかまいませんが、おそらく何らかのIO::Handleが必要です。:)

UPDATE 1への応答:

トレースを見ると、次のことがわかります。

IO::SessionData::new('IO::LineBufferedSessionData', 'IO::LineBufferedSet=HASH(0x7fcbe19bd450)', 'IO::Socket::INET=GLOB(0x7fcbe18a8070)', undef) 

メソッドを呼び出すものとして。はIO::Socket::INETIO::SocketあるIO::Handleため、メソッドを使用できるようにする必要が->blocking()あります。21行目は何ですか?

于 2013-01-15T01:25:11.137 に答える