libwww-perl / HTTP-Message

The HTTP-Message distribution contains classes useful for representing the messages passed in HTTP style communication.

Home Page:https://metacpan.org/pod/HTTP::Message

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

`can` method doesn't repond to delegated methods

nanto opened this issue · comments

can method of HTTP::Message returns undef for a method that is delegated to HTTP::Headers if that method is not yet called.

my $m = HTTP::Message->new(['User-Agent' => 'Mozilla/5.0']);
say $m->can('user_agent') ? 'yes' : 'no';
# Actual: 'no'
# Expected: 'yes'

$m->user_agent;
say $m->can('user_agent') ? 'yes' : 'no';
# Once we call the `user_agent` method, the result becomes 'yes'.

This behavior doesn't follow https://perldoc.perl.org/perlobj#AUTOLOAD

If your class does have an AUTOLOAD method, we strongly recommend that you override can in your class as well. Your overridden can method should return a subroutine reference for any method that your AUTOLOAD responds to.

I'm afraid I can't verify method call with Test2::V0 because Test2::V0 checks the given method name with can method.

use strict;
use warnings;
use Test2::V0;
use HTTP::Message;

my $m = HTTP::Message->new(['User-Agent' => 'Mozilla/5.0']);
is $m, object {
    call user_agent => 'Mozilla/5.0';
};
# not ok 1
# Failed test at test.t line 9.
# +--------------+------------------------------------+-------------+------+
# | PATH         | GOT                                | CHECK       | LNs  |
# +--------------+------------------------------------+-------------+------+
# |              | HTTP::Message=HASH(0x5599233aa860) | <OBJECT>    | 8, 8 |
# | user_agent() | <DOES NOT EXIST>                   | Mozilla/5.0 | 484  |
# +--------------+------------------------------------+-------------+------+

# Workaround: use `call sub { ... }` pattern.
is $m, object {
    call sub { $_[0]->user_agent } => 'Mozilla/5.0';
};
# ok 2

done_testing;