proyectos ejemplos perl function module subroutine

perl - ejemplos - django



En Perl, ¿cómo puedo verificar desde qué módulo se importó una función determinada? (4)

Tengo un código que llama a la función. Pero no conozco el módulo al que pertenece esta función. Lo necesito para modificar esta función.

¿Cómo puedo comprobarlo?


El depurador de Perl puede excavar como tú quieras. Por ejemplo:

main::(-e:1): 0 DB<1> sub foo {} DB<2> x /&foo 0 CODE(0xca6898) -> &main::foo in (eval 5)[/usr/share/perl/5.10/perl5db.pl:638]:2-2

Lo hace usando Devel::Peek :

=head2 C<CvGV_name_or_bust> I<coderef> Calls L<Devel::Peek> to try to find the glob the ref lives in; returns C<undef> if L<Devel::Peek> can''t be loaded, or if C<Devel::Peek::CvGV> can''t find a glob for this ref. Returns C<< I<package>::I<glob name> >> if the code ref is found in a glob. =cut sub CvGV_name_or_bust { my $in = shift; return unless ref $in; $in = /&$in; # Hard reference... eval { require Devel::Peek; 1 } or return; my $gv = Devel::Peek::CvGV($in) or return; *$gv{PACKAGE} . ''::'' . *$gv{NAME}; } ## end sub CvGV_name_or_bust

Podrías ejercitarlo con

#! /usr/bin/perl use warnings; use strict; package Foo; sub bar {} package main; BEGIN { *baz = /&Foo::bar } sub CvGV_name_or_bust { ... } print CvGV_name_or_bust(/&baz), "/n";

Salida:

Foo::bar

Tenga en cuenta que el ejemplo anterior le da a Foo:bar un nombre diferente, pero obtendrá tanto el paquete donde residen los sub alias como su nombre allí.


Puede pasar a Sub::Identify::sub_fullname cualquier referencia de subrutina y le mostrará el módulo donde se definió este sub:

use Sub::Identify qw/sub_fullname/; sub foo { print sub_fullname( /&foo ); # main::foo print sub_fullname( sub{} ); # main::__ANON__ } foo();

Para más detalles ver Sub::Identify


Si la función se importó automáticamente de otro módulo utilizando Exporter , se puede encontrar en la variable global @EXPORT este módulo:

perl -MEncode -e ''print join "/n", @Encode::EXPORT'' decode decode_utf8 ...

Puede proporcionar una lista de funciones para use . De esta manera siempre sabrás a qué paquete pertenece una función:

use Encode qw[ encode ]; # encode() imported from the Encode module use Data::Dumper qw[]; # no functions imported from Data::Dumper


El módulo Devel::Peek es muy útil para obtener todo tipo de información sobre variables. Una de las cosas que puede hacer con esto es volcar una referencia a una subrutina y obtener el nombre del globo del que proviene:

$ perl -MDevel::Peek -MList::Util=first -e''Dump(/&first)'' SV = IV(0x1094e20) at 0x1094e28 REFCNT = 1 FLAGS = (TEMP,ROK) RV = 0x11183b0 SV = PVCV(0x10ff1f0) at 0x11183b0 REFCNT = 3 FLAGS = (POK,pPOK) PROTOTYPE = "&@" COMP_STASH = 0x0 XSUB = 0x7f7ecbdc61b0 XSUBANY = 0 GVGV::GV = 0x11183c8 "List::Util" :: "first" FILE = "ListUtil.c" DEPTH = 0 FLAGS = 0x800 OUTSIDE_SEQ = 0 PADLIST = 0x0 OUTSIDE = 0x0 (null)

La parte GVGV::GV allí es la parte importante.

Una solución alternativa sería Sub::Identify , que en realidad solo te da nombres para las referencias de código que le das. Sin embargo, saber sobre Devel::Peek es útil en muchas otras situaciones, así que mencioné eso primero.