File Coverage

blib/lib/Protocol/IRC.pm
Criterion Covered Total %
statement 135 151 89.4
branch 63 96 65.6
condition 10 17 58.8
subroutine 22 26 84.6
pod 17 21 80.9
total 247 311 79.4


line stmt bran cond sub pod time code
1             # You may distribute under the terms of either the GNU General Public License
2             # or the Artistic License (the same terms as Perl itself)
3             #
4             # (C) Paul Evans, 2010-2015 -- leonerd@leonerd.org.uk
5              
6             package Protocol::IRC;
7              
8 6     6   133293 use strict;
  6         18  
  6         195  
9 6     6   34 use warnings;
  6         17  
  6         281  
10              
11             our $VERSION = '0.11';
12              
13 6     6   41 use Carp;
  6         13  
  6         498  
14              
15 6     6   4166 use Protocol::IRC::Message;
  6         15  
  6         13858  
16              
17             # This should be mixed in MI-style
18              
19             =head1 NAME
20              
21             C - IRC protocol handling
22              
23             =head1 DESCRIPTION
24              
25             This mix-in class provides a base layer of IRC message handling logic. It
26             allows reading of IRC messages from a string buffer and dispatching them to
27             handler methods on its instance.
28              
29             L provides an extension to this logic that may be more
30             convenient for IRC client implementations.
31              
32             =head1 MESSAGE HANDLING
33              
34             Every incoming message causes a sequence of message handling to occur. First,
35             the message is parsed, and a hash of data about it is created; this is called
36             the hints hash. The message and this hash are then passed down a sequence of
37             potential handlers.
38              
39             Each handler indicates by return value, whether it considers the message to
40             have been handled. Processing of the message is not interrupted the first time
41             a handler declares to have handled a message. Instead, the hints hash is marked
42             to say it has been handled. Later handlers can still inspect the message or its
43             hints, using this information to decide if they wish to take further action.
44              
45             A message with a command of C will try handlers in following places:
46              
47             =over 4
48              
49             =item 1.
50              
51             A method called C
52              
53             $irc->on_message_COMMAND( $message, \%hints )
54              
55             =item 2.
56              
57             A method called C
58              
59             $irc->on_message( 'COMMAND', $message, \%hints )
60              
61             =back
62              
63             For server numeric replies, if the numeric reply has a known name, it will be
64             attempted first at its known name, before falling back to the numeric if it
65             was not handled. Unrecognised numerics will be attempted only at their numeric
66             value.
67              
68             Because of the wide variety of messages in IRC involving various types of data
69             the message handling specific cases for certain types of message, including
70             adding extra hints hash items, or invoking extra message handler stages. These
71             details are noted here.
72              
73             Many of these messages create new events; called synthesized messages. These
74             are messages created by the C object itself, to better
75             represent some of the details derived from the primary ones from the server.
76             These events all take lower-case command names, rather than capitals, and will
77             have a C key in the hints hash, set to a true value. These are
78             dispatched and handled identically to regular primary events, detailed above.
79              
80             If any handler of the synthesized message returns true, then this marks the
81             primary message handled as well.
82              
83             If a message is received that has a gating disposition, extra processing is
84             applied to it before the processing above. The effect on its gate is given as
85             a string (one of C, C, C) to handlers in the following
86             places:
87              
88             =over 4
89              
90             =item 1.
91              
92             A method called C
93              
94             $irc->on_message_gate_EFFECT_GATE( $message, \%hints )
95              
96             =item 2.
97              
98             A method called C
99              
100             $irc->on_message_gate_EFFECT( 'GATE', $message, \%hints )
101              
102             =item 3.
103              
104             A method called C
105              
106             $irc->on_message_gate( 'EFFECT', 'GATE', $message, \%hints )
107              
108             =back
109              
110             =head2 Message Hints
111              
112             When messages arrive they are passed to the appropriate message handling
113             method, which the implementation may define. As well as the message, a hash
114             of extra information derived from or relating to the message is also given.
115              
116             The following keys will be present in any message hint hash:
117              
118             =over 8
119              
120             =item handled => BOOL
121              
122             Initially false. Will be set to true the first time a handler returns a true
123             value.
124              
125             =item prefix_nick => STRING
126              
127             =item prefix_user => STRING
128              
129             =item prefix_host => STRING
130              
131             Values split from the message prefix; see the C
132             C method.
133              
134             =item prefix_name => STRING
135              
136             Usually the prefix nick, or the hostname in case the nick isn't defined
137             (usually on server messages).
138              
139             =item prefix_is_me => BOOL
140              
141             True if the nick mentioned in the prefix refers to this connection.
142              
143             =back
144              
145             Added to this set, will be all the values returned by the message's
146             C method. Some of these values may cause yet more values to be
147             generated.
148              
149             If the message type defines a C:
150              
151             =over 8
152              
153             =item * target_type => STRING
154              
155             Either C or C, as returned by C.
156              
157             =item * target_is_me => BOOL
158              
159             True if the target name is a user and refers to this connection.
160              
161             =back
162              
163             Any key whose name ends in C<_nick> or C<_name> will have a corresponding key
164             added with C<_folded> suffixed on its name, containing the value casefolded
165             using C. This is for the convenience of string comparisons,
166             hash keys, etc..
167              
168             Any of these keys that are not the C will additionally have a
169             corresponding key with C<_is_me> replacing the C<_nick> or C<_name>,
170             containing the boolean result of calling the C method on that
171             name. This makes it simpler to detect commands or results affecting the user
172             the connection represents.
173              
174             =cut
175              
176             =head1 METHODS
177              
178             =cut
179              
180             =head2 on_read
181              
182             $irc->on_read( $buffer )
183              
184             Informs the protocol implementation that more bytes have been read from the
185             peer. This method will modify the C<$buffer> directly, and remove from it the
186             prefix of bytes it has consumed. Any bytes remaining should be stored by the
187             caller for next time.
188              
189             Any messages found in the buffer will be passed, in sequence, to the
190             C method.
191              
192             =cut
193              
194             sub on_read
195             {
196 18     18 1 4167 my $self = shift;
197             # buffer in $_[0]
198              
199 18         128 while( $_[0] =~ s/^(.*)\x0d\x0a// ) {
200 19         46 my $line = $1;
201             # Ignore blank lines
202 19 100       62 next if !length $line;
203              
204 17         74 $self->incoming_message( Protocol::IRC::Message->new_from_line( $line ) );
205             }
206             }
207              
208             =head2 incoming_message
209              
210             $irc->incoming_message( $message )
211              
212             Invoked by the C method for every incoming IRC message. This method
213             implements the actual dispatch into various handler methods as described in
214             the L section above.
215              
216             This method is exposed so that subclasses can override it, primarily to wrap
217             extra logic before or after the main dispatch (e.g. for logging or other
218             processing).
219              
220             =cut
221              
222             sub incoming_message
223             {
224 17     17 1 25 my $self = shift;
225 17         28 my ( $message ) = @_;
226              
227 17         58 my $command = $message->command_name;
228              
229 17         64 my ( $prefix_nick, $prefix_user, $prefix_host ) = $message->prefix_split;
230              
231 17 100       101 my $hints = {
232             handled => 0,
233              
234             prefix_nick => $prefix_nick,
235             prefix_user => $prefix_user,
236             prefix_host => $prefix_host,
237             # Most of the time this will be "nick", except for special messages from the server
238             prefix_name => defined $prefix_nick ? $prefix_nick : $prefix_host,
239             };
240              
241 17 100       62 if( my $named_args = $message->named_args ) {
242 16         82 $hints->{$_} = $named_args->{$_} for keys %$named_args;
243             }
244              
245 17 100 100     116 if( defined $hints->{text} and my $encoder = $self->encoder ) {
246 2         24 $hints->{text} = $encoder->decode( $hints->{text} );
247             }
248              
249 17 100       70 if( defined( my $target_name = $hints->{target_name} ) ) {
250 2         5 my $target_type = $self->classify_name( $target_name );
251 2         24 $hints->{target_type} = $target_type;
252             }
253              
254 17         32 my $prepare_method = "prepare_hints_$command";
255 17 50       126 $self->$prepare_method( $message, $hints ) if $self->can( $prepare_method );
256              
257 17 100       61 foreach my $k ( grep { m/_nick$/ or m/_name$/ } keys %$hints ) {
  118         559  
258 40         133 $hints->{"${k}_folded"} = $self->casefold_name( my $name = $hints->{$k} );
259 40 100       109 defined $name or next;
260 37 100       104 $k eq "prefix_name" and next;
261              
262 20         115 ( my $knew = $k ) =~ s/_name$|_nick$/_is_me/;
263 20         61 $hints->{$knew} = $self->is_nick_me( $name );
264             }
265              
266 17 50       97 if( my $disp = $message->gate_disposition ) {
267 0         0 my ( $type, $gate ) = $disp =~ m/^([-+!])(.*)$/;
268 0 0       0 my $effect = ( $type eq "-" ? "more" :
    0          
    0          
269             $type eq "+" ? "done" :
270             $type eq "!" ? "fail" : die "TODO" );
271              
272 0 0       0 $self->invoke( "on_message_gate_${effect}_$gate", $message, $hints ) and $hints->{handled} = 1;
273 0 0       0 $self->invoke( "on_message_gate_$effect", $gate, $message, $hints ) and $hints->{handled} = 1;
274 0 0       0 $self->invoke( "on_message_gate", $effect, $gate, $message, $hints ) and $hints->{handled} = 1;
275             }
276              
277 17 100       80 $self->invoke( "on_message_$command", $message, $hints ) and $hints->{handled} = 1;
278 17 100       58 $self->invoke( "on_message", $command, $message, $hints ) and $hints->{handled} = 1;
279              
280 17 50 66     269 if( !$hints->{handled} and $message->command ne $command ) { # numerics
281 0         0 my $numeric = $message->command;
282 0 0       0 $self->invoke( "on_message_$numeric", $message, $hints ) and $hints->{handled} = 1;
283 0 0       0 $self->invoke( "on_message", $numeric, $message, $hints ) and $hints->{handled} = 1;
284             }
285             }
286              
287             =head2 send_message
288              
289             $irc->send_message( $message )
290              
291             Sends a message to the peer from the given C
292             object.
293              
294             $irc->send_message( $command, $prefix, @args )
295              
296             Sends a message to the peer directly from the given arguments.
297              
298             =cut
299              
300             sub send_message
301             {
302 4     4 1 31 my $self = shift;
303              
304 4         7 my $message;
305              
306 4 50       15 if( @_ == 1 ) {
307 0         0 $message = shift;
308             }
309             else {
310 4         13 my ( $command, $prefix, @args ) = @_;
311              
312 4 100       20 if( my $encoder = $self->encoder ) {
313 1         4 my $argnames = Protocol::IRC::Message->arg_names( $command );
314              
315 1 50       5 if( defined( my $i = $argnames->{text} ) ) {
316 1 50       43 $args[$i] = $encoder->encode( $args[$i] ) if defined $args[$i];
317             }
318             }
319              
320 4         25 $message = Protocol::IRC::Message->new( $command, $prefix, @args );
321             }
322              
323 4         28 $self->write( $message->stream_to_line . "\x0d\x0a" );
324             }
325              
326             =head2 send_ctcp
327              
328             $irc->send_ctcp( $prefix, $target, $verb, $argstr )
329              
330             Shortcut to sending a CTCP message. Sends a PRIVMSG to the given target,
331             containing the given verb and argument string.
332              
333             =cut
334              
335             sub send_ctcp
336             {
337 1     1 1 2 my $self = shift;
338 1         3 my ( $prefix, $target, $verb, $argstr ) = @_;
339              
340 1         10 $self->send_message( "PRIVMSG", undef, $target, "\001$verb $argstr\001" );
341             }
342              
343             =head2 send_ctcprely
344              
345             $irc->send_ctcprely( $prefix, $target, $verb, $argstr )
346              
347             Shortcut to sending a CTCP reply. As C but using a NOTICE instead.
348              
349             =cut
350              
351             sub send_ctcpreply
352             {
353 1     1 0 3 my $self = shift;
354 1         2 my ( $prefix, $target, $verb, $argstr ) = @_;
355              
356 1         5 $self->send_message( "NOTICE", undef, $target, "\001$verb $argstr\001" );
357             }
358              
359             =head1 ISUPPORT-DRIVEN UTILITIES
360              
361             The following methods are controlled by the server information given in the
362             C settings. They use the C required method to query the
363             information required.
364              
365             =cut
366              
367             =head2 casefold_name
368              
369             $name_folded = $irc->casefold_name( $name )
370              
371             Returns the C<$name>, folded in case according to the server's C
372             C. Such a folded name will compare using C according to whether the
373             server would consider it the same name.
374              
375             Useful for use in hash keys or similar.
376              
377             =cut
378              
379             sub casefold_name
380             {
381 106     106 1 194 my $self = shift;
382 106         159 my ( $nick ) = @_;
383              
384 106 100       236 return undef unless defined $nick;
385              
386 103   100     258 my $mapping = lc( $self->isupport( "CASEMAPPING" ) || "" );
387              
388             # Squash the 'capital' [\] into lowercase {|}
389 103 100       691 $nick =~ tr/[\\]/{|}/ if $mapping ne "ascii";
390              
391             # Most RFC 1459 implementations also squash ^ to ~, even though the RFC
392             # didn't mention it
393 103 100       253 $nick =~ tr/^/~/ unless $mapping eq "strict-rfc1459";
394              
395 103         447 return lc $nick;
396             }
397              
398             =head2 cmp_prefix_flags
399              
400             $cmp = $irc->cmp_prefix_flags( $lhs, $rhs )
401              
402             Compares two channel occupant prefix flags, and returns a signed integer to
403             indicate which of them has higher priviledge, according to the server's
404             ISUPPORT declaration. Suitable for use in a C function or similar.
405              
406             =cut
407              
408             sub cmp_prefix_flags
409             {
410 4     4 1 497 my $self = shift;
411 4         6 my ( $lhs, $rhs ) = @_;
412              
413 4 50 33     24 return undef unless defined $lhs and defined $rhs;
414              
415             # As a special case, compare emptystring as being lower than voice
416 4 50 33     13 return 0 if $lhs eq "" and $rhs eq "";
417 4 50       34 return 1 if $rhs eq "";
418 4 50       11 return -1 if $lhs eq "";
419              
420 4         11 my $PREFIX_FLAGS = $self->isupport( 'prefix_flags' );
421              
422 4 50       23 ( my $lhs_index = index $PREFIX_FLAGS, $lhs ) > -1 or return undef;
423 4 100       18 ( my $rhs_index = index $PREFIX_FLAGS, $rhs ) > -1 or return undef;
424              
425             # IRC puts these in greatest-first, so we need to swap the ordering here
426 3         14 return $rhs_index <=> $lhs_index;
427             }
428              
429             =head2 cmp_prefix_modes
430              
431             $cmp = $irc->cmp_prefix_modes( $lhs, $rhs )
432              
433             Similar to C, but compares channel occupant C command
434             flags.
435              
436             =cut
437              
438             sub cmp_prefix_modes
439             {
440 4     4 1 8 my $self = shift;
441 4         8 my ( $lhs, $rhs ) = @_;
442              
443 4 50 33     24 return undef unless defined $lhs and defined $rhs;
444              
445 4         10 my $PREFIX_MODES = $self->isupport( "prefix_modes" );
446              
447 4 50       23 ( my $lhs_index = index $PREFIX_MODES, $lhs ) > -1 or return undef;
448 4 100       13 ( my $rhs_index = index $PREFIX_MODES, $rhs ) > -1 or return undef;
449              
450             # IRC puts these in greatest-first, so we need to swap the ordering here
451 3         13 return $rhs_index <=> $lhs_index;
452             }
453              
454             =head2 prefix_mode2flag
455              
456             $flag = $irc->prefix_mode2flag( $mode )
457              
458             Converts a channel occupant C flag (such as C) into a name prefix
459             flag (such as C<@>).
460              
461             =cut
462              
463             sub prefix_mode2flag
464             {
465 1     1 1 3399 my $self = shift;
466 1         3 my ( $mode ) = @_;
467              
468 1         4 return $self->isupport( 'prefix_map_m2f' )->{$mode};
469             }
470              
471             =head2 prefix_flag2mode
472              
473             $mode = $irc->prefix_flag2mode( $flag )
474              
475             The inverse of C.
476              
477             =cut
478              
479             sub prefix_flag2mode
480             {
481 1     1 1 520 my $self = shift;
482 1         2 my ( $flag ) = @_;
483              
484 1         5 return $self->isupport( 'prefix_map_f2m' )->{$flag};
485             }
486              
487             =head2 classify_name
488              
489             $classification = $irc->classify_name( $name )
490              
491             Returns C if the given name matches the pattern of names allowed for
492             channels according to the server's C C. Returns C
493             if not.
494              
495             =cut
496              
497             sub classify_name
498             {
499 14     14 1 24 my $self = shift;
500 14         22 my ( $name ) = @_;
501              
502 14 100       41 return "channel" if $name =~ $self->isupport( "channame_re" );
503 6         54 return "user"; # TODO: Perhaps we can be a bit stricter - only check for valid nick chars?
504             }
505              
506             =head2 is_nick_me
507              
508             $me = $irc->is_nick_me( $nick )
509              
510             Returns true if the given nick refers to that in use by the connection.
511              
512             =cut
513              
514             sub is_nick_me
515             {
516 25     25 1 34 my $self = shift;
517 25         36 my ( $nick ) = @_;
518              
519 25         52 return $self->casefold_name( $nick ) eq $self->nick_folded;
520             }
521              
522             =head1 INTERNAL MESSAGE HANDLING
523              
524             The following messages are handled internally by C.
525              
526             =cut
527              
528             =head2 PING
529              
530             C messages are automatically replied to with C.
531              
532             =cut
533              
534             sub on_message_PING
535             {
536 0     0 0 0 my $self = shift;
537 0         0 my ( $message, $hints ) = @_;
538              
539 0         0 $self->send_message( "PONG", undef, $message->named_args->{text} );
540              
541 0         0 return 1;
542             }
543              
544             =head2 NOTICE and PRIVMSG
545              
546             Because C and C are so similar, they are handled together by
547             synthesized events called C, C and C. Depending on the
548             contents of the text, and whether it was supplied in a C or a
549             C, one of these three events will be created.
550              
551             In all cases, the hints hash will contain a C key being true or
552             false, depending on whether the original messages was a C or a
553             C, a C key containing the message target name, a
554             case-folded version of the name in a C key, and a
555             classification of the target type in a C key.
556              
557             For the C target type, it will contain a boolean in C to
558             indicate if the target of the message is the user represented by this
559             connection.
560              
561             For the C target type, it will contain a C key
562             containing the channel message restriction, if present.
563              
564             For normal C messages, it will contain a key C containing the
565             actual message text.
566              
567             For either CTCP message type, it will contain keys C and
568             C with the parsed message. The C will contain the first
569             space-separated token, and C will be a string containing the rest
570             of the line, otherwise unmodified. This type of message is also subject to a
571             special stage of handler dispatch, involving the CTCP verb string. For
572             messages with C as the verb, the following are tried. C may stand
573             for either C or C.
574              
575             =over 4
576              
577             =item 1.
578              
579             A method called C
580              
581             $irc->on_message_CTCP_VERB( $message, \%hints )
582              
583             =item 2.
584              
585             A method called C
586              
587             $irc->on_message_CTCP( 'VERB', $message, \%hintss )
588              
589             =item 3.
590              
591             A method called C
592              
593             $irc->on_message( 'CTCP VERB', $message, \%hints )
594              
595             =back
596              
597             =cut
598              
599             sub on_message_NOTICE
600             {
601 3     3 0 5 my $self = shift;
602 3         8 my ( $message, $hints ) = @_;
603 3         8 return $self->_on_message_text( $message, $hints, 1 );
604             }
605              
606             sub on_message_PRIVMSG
607             {
608 7     7 0 13 my $self = shift;
609 7         17 my ( $message, $hints ) = @_;
610 7         26 return $self->_on_message_text( $message, $hints, 0 );
611             }
612              
613             sub _on_message_text
614             {
615 10     10   12 my $self = shift;
616 10         19 my ( $message, $hints, $is_notice ) = @_;
617              
618 10         89 my %hints = (
619             %$hints,
620             synthesized => 1,
621             is_notice => $is_notice,
622             );
623              
624             # TODO: In client->server messages this might be a comma-separated list
625 10         28 my $target = delete $hints{targets};
626              
627 10         33 my $prefixflag_re = $self->isupport( 'prefixflag_re' );
628              
629 10         41 my $restriction = "";
630 10         116 while( $target =~ m/^$prefixflag_re/ ) {
631 1         8 $restriction .= substr( $target, 0, 1, "" );
632             }
633              
634 10         23 $hints{target_name} = $target;
635 10         39 $hints{target_name_folded} = $self->casefold_name( $target );
636              
637 10         36 my $type = $hints{target_type} = $self->classify_name( $target );
638              
639 10 100       72 if( $type eq "channel" ) {
    50          
640 5         13 $hints{restriction} = $restriction;
641 5         22 $hints{target_is_me} = '';
642             }
643             elsif( $type eq "user" ) {
644             # TODO: user messages probably can't have restrictions. What to do
645             # if we got one?
646 5         12 $hints{target_is_me} = $self->is_nick_me( $target );
647             }
648              
649 10         22 my $text = $hints->{text};
650              
651 10 100       49 if( $text =~ m/^\x01(.*)\x01$/ ) {
652 2         8 ( my $verb, $text ) = split( m/ /, $1, 2 );
653 2         17 $hints{ctcp_verb} = $verb;
654 2         5 $hints{ctcp_args} = $text;
655              
656 2 100       5 my $ctcptype = $is_notice ? "ctcpreply" : "ctcp";
657              
658 2 50       8 $self->invoke( "on_message_${ctcptype}_$verb", $message, \%hints ) and $hints{handled} = 1;
659 2 50       9 $self->invoke( "on_message_${ctcptype}", $verb, $message, \%hints ) and $hints{handled} = 1;
660 2 50       8 $self->invoke( "on_message", "$ctcptype $verb", $message, \%hints ) and $hints{handled} = 1;
661             }
662             else {
663 8         14 $hints{text} = $text;
664              
665 8 100       32 $self->invoke( "on_message_text", $message, \%hints ) and $hints{handled} = 1;
666 8 100       31 $self->invoke( "on_message", "text", $message, \%hints ) and $hints{handled} = 1;
667             }
668              
669 10         122 return $hints{handled};
670             }
671              
672             =head1 REQUIRED METHODS
673              
674             =cut
675              
676             =head2 write
677              
678             $irc->write( $string )
679              
680             Requests the byte string to be sent to the peer
681              
682             =cut
683              
684 0     0 1 0 sub write { croak "Attemped to invoke abstract ->write on " . ref $_[0] }
685              
686             =head2 encoder
687              
688             $encoder = $irc->encoder
689              
690             Optional. If supplied, returns an L object used to encode or decode
691             the bytes appearing in a C field of a message. If set, all text strings
692             will be returned, and should be given, as Unicode strings. They will be
693             encoded or decoded using this object.
694              
695             =cut
696              
697 16     16 1 68 sub encoder { undef }
698              
699             =head2 invoke
700              
701             $result = $irc->invoke( $name, @args )
702              
703             Optional. If provided, invokes the message handling routine called C<$name>
704             with the given arguments. A default implementation is provided which simply
705             attempts to invoke a method of the given name, or return false if no method
706             of that name exists.
707              
708             If an implementation does override this method, care should be taken to ensure
709             that methods are tested for and invoked if present, in addition to any other
710             work the method wishes to perform, as this is the basis by which derived
711             message handling works.
712              
713             =cut
714              
715             sub invoke
716             {
717 56     56 1 72 my $self = shift;
718 56         125 my ( $name, @args ) = @_;
719 56 100       305 return unless $self->can( $name );
720 37         115 return $self->$name( @args );
721             }
722              
723             =head2 isupport
724              
725             $value = $irc->isupport( $field )
726              
727             Should return the value of the given C field.
728              
729             As well as the all-capitals server-supplied fields, the following fields may
730             be requested. Their names are all lowercase and contain underscores, to
731             distinguish them from server-supplied fields.
732              
733             =over 8
734              
735             =item prefix_modes => STRING
736              
737             The mode characters from C (e.g. C)
738              
739             =item prefix_flags => STRING
740              
741             The flag characters from C (e.g. C<@%+>)
742              
743             =item prefixflag_re => Regexp
744              
745             A precompiled regexp that matches any of the prefix flags
746              
747             =item prefix_map_m2f => HASH
748              
749             A map from mode characters to flag characters
750              
751             =item prefix_map_f2m => HASH
752              
753             A map from flag characters to mode characters
754              
755             =item chanmodes_list => ARRAY
756              
757             A 4-element array containing the split portions of C;
758              
759             [ $listmodes, $argmodes, $argsetmodes, $boolmodes ]
760              
761             =item channame_re => Regexp
762              
763             A precompiled regexp that matches any string beginning with a channel prefix
764             character in C.
765              
766             =back
767              
768             =cut
769              
770 0     0 1 0 sub isupport { croak "Attempted to invoke abstract ->isupport on " . ref $_[0] }
771              
772             =head2 nick
773              
774             $nick = $irc->nick
775              
776             Should return the current nick in use by the connection.
777              
778             =head2 nick_folded
779              
780             $nick_folded = $irc->nick_folded
781              
782             Optional. If supplied, should return the current nick as case-folded by the
783             C method. If not provided, this will be performed by
784             case-folding the result from C.
785              
786             =cut
787              
788 0     0 1 0 sub nick { croak "Attempted to invoke abstract ->nick on " . ref $_[0] }
789 25     25 1 72 sub nick_folded { $_[0]->casefold_name( $_[0]->nick ) }
790              
791             =head1 AUTHOR
792              
793             Paul Evans
794              
795             =cut
796              
797             0x55AA;