检测 perl 中声明的包变量

2024-05-10

Given

# package main;
our $f;
sub f{}
sub g {}
1;

我怎样才能确定$f, 但不是$g,已宣布?即兴的,我以为*{main::g}{SCALAR}可能是未定义的,但它是一个善意标量参考值

背景:我想将一个变量导入到main::,但如果该变量已经声明,则会发出鲤鱼或呱呱叫声。

EDIT添加了一个f子例程响应@DVK的最初答案。

答(2010-07-27)

这并不容易,但这是可能的。

An eval技术 https://stackoverflow.com/questions/3335425/detecting-declared-package-variables-in-perl/3336806#3336806是最可移植的,可以在 5.10 之前的 perls 上运行。在最近的 perls 中,内省模块如Devel::Peek https://stackoverflow.com/questions/3335425/detecting-declared-package-variables-in-perl/3336535#3336535 and B https://stackoverflow.com/questions/3335425/detecting-declared-package-variables-in-perl/3337046#3337046可以歧视。


SUMMARY

在这一点上,经过相当广泛的研究,我坚信,在声明了名称为“X”的符号表条目但未分配给它的情况下,它是无法笼统区分glob 中的哪些引用类型实际上是在没有使用 Devil:: stuff 的深度探测的情况下声明的。

换句话说,您只能区分以下两种不同的情况:

  1. X 根本没有声明(符号表条目不存在)

  2. X 已声明,并且实际分配了一些 glob 类型。

    在第二种情况下,

    • You can查找哪些 glob 类型已分配给哪些类型,哪些未分配给这些类型

    • 但是你can not找出哪些未分配的 glob 类型是声明且未分配的,哪些是根本没有声明的。

    换句话说,对于our $f = 1; our @f;;我们可以说$main::f是一个标量; 但我们无法判断是否@f and %f是否已声明 - 它与our $f = 1; our %f; .

    请注意,子例程定义也遵循第二条规则,但声明命名子会自动为其分配一个值(代码块),因此您永远不能让子名称处于“已声明但未分配给”状态(警告:对于原型来说可能不是这样???没有线索)。

原答案

好吧,区分标量和子例程的非常有限(恕我直言有点脆弱)的解决方案可能是使用 UNIVERSAL::can:

use strict; 
our $f; 
sub g {};
foreach my $n ("f","g","h") {
    # First off, check if we are in main:: namespace, 
    # and if we are, that we are a scalar
    no strict "refs"; 
    next unless exists $main::{$n} && *{"main::$n"}; 
    use strict "refs"; 
    # Now, we are a declared scalr, unless we are a executable subroutine:
    print "Declared: \$$n\n" unless UNIVERSAL::can("main",$n)
}

Result:

Declared: $f

请注意{SCALAR}在我的测试中似乎无法清除非标量 - 它很高兴地通过了@A and %H如果我声明它们并添加到循环中。

UPDATE

我尝试了《Mastering Perl》第 8 章中的 Brian d Foy 的方法,但不知何故无法让它适用于标量、散列或数组;但正如下面 draegtun 所指出的,它适用于子例程或变量已经分配给:

> perl5.8 -we '{use strict; use Data::Dumper; 
  our $f; sub g {}; our @A=(); sub B{}; our $B; our %H=();
  foreach my $n ("f","g","h","STDOUT","A","H","B") {
      no strict "refs"; 
      next unless exists $main::{$n};
      print "Exists: $n\n";
      if ( defined ${$n}) { print "Defined scalar: $n\n"}; 
      if ( defined @{$n}) { print "Defined ARRAY: $n\n"}; 
      if ( defined %{$n}) { print "Defined HASH: $n\n"}; 
      if ( defined &{$n}) { print "Defined SUB: $n\n"}; 
      use strict "refs";}}'       

Exists: f
Exists: g
Defined SUB: g           <===== No other defined prints worked
Exists: STDOUT
Exists: A
Exists: H
Exists: B
Defined SUB: B           <===== No other defined prints worked
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

检测 perl 中声明的包变量 的相关文章

随机推荐

  • 响应覆盖 div 下的链接

    场景是这样的 我已经构建了一个顶部导航原型 它需要在其顶部有一个覆盖 透明 PNG 图像 目前它覆盖了大约 1 3 的链接 请看下面 有什么方法可以让前 1 3 的链接做出响应 即使有一个 div div 部分覆盖它们 覆盖层不会包含任何可
  • 使用 Maven 3 时 Cobertura 代码覆盖率为 0%

    读完这篇文章后 将 Cobertura 与 Maven 3 0 2 一起使用的正确方法是什么 https stackoverflow com questions 6931360 what is the proper way to use c
  • python csv按列转换为字典

    是否可以将 csv 文件中的数据读取到字典中 使得列的第一行是键 同一列的其余行构成列表的值 例如 我有一个 csv 文件 strings numbers colors string1 1 blue string2 2 red string
  • 将字符串中的字符向左移动

    我是 Stack Overflow 的新手 有一道编程课的实验室问题一直困扰着我 该问题要求我们将字符串 s 的元素向左移动 k 次 例如 如果输入是 Hello World 和3 它将输出 lo WorldHel 对于非常大的 k 值 它
  • Haskell 中的实例声明

    我有这两个功能 primes sieve 2 where sieve p xs p sieve x x lt xs x mod p gt 0 isPrime number number 1 null x x lt takeWhile x g
  • 如何跟踪数据库连接泄漏

    我们有一个应用程序似乎存在连接泄漏 SQL Server 表示已达到最大池大小 我独自一人在我的开发机器上 显然 只需导航应用程序 我就会触发此错误 SQL Server 活动监视器显示大量正在使用我的数据库的进程 我想查找哪些文件打开连接
  • Scala repl 抛出错误

    当我打字时scala在终端上启动 repl 它会抛出此错误 scala gt init error error while loading AnnotatedElement class file usr lib jvm java 8 ora
  • Android:如何为我的应用程序播放的任何音乐文件创建淡入/淡出音效?

    我正在开发的应用程序播放音乐文件 如果计时器到期 我希望音乐淡出 我怎么做 我正在使用 MediaPlayer 播放音乐 音乐文件位于我的应用程序的原始文件夹中 这是我的 Android MediaPlayer 的整个处理程序类 查看 pl
  • 具有 MVC4 风格捆绑的 Intellisense

    到目前为止我找不到问题或解决这个问题 我确信我错过了一些简单的事情 我有一个带有一堆缩小的 CSS 的样式包 并且我正在用里面的类来装饰 HTML 元素 一切都运转良好 然而 Intellisense 和 ReSharper 都因为 CSS
  • DRF:以编程方式从 TextChoices 字段获取默认选择

    我们的网站是 Vue 前端 DRF 后端 在一个serializer validate 方法 我需要以编程方式确定哪个选项TextChoices类已被指定为模型字段的默认值 TextChoices 类 缩写示例 class PaymentM
  • Angular 2 变更检测是如何工作的?

    在 Angular 1 中 更改检测是通过对 scope 层次结构进行脏检查来进行的 我们会在模板 控制器或组件中隐式或显式创建观察者 在 Angular 2 中 我们不再有 scope 但我们确实重写了 setInterval setTi
  • VS C# 中的依赖地狱,找不到依赖项

    我创建了一个图表 C 库 我们称之为chartlibrary 它本身依赖于多个第三方 dll 文件 在另一个可执行项目中 我们称之为chartuser 我参考了chartlibrary项目 两个项目位于 Visual Studio 中的同一
  • HTML 文本框,自动突出显示文本

    我将如何制作一个包含预先存在的文本的文本框 当用户在其中单击时 其中的所有文本都会突出显示 例如 YouTube 在其视频上使用嵌入代码的文本框的方式相同 谢谢 如果我正确理解你的问题 你可以使用一些javascript 未经测试的代码
  • 为什么 std::atomic 比 volatile bool 慢很多?

    多年来我一直使用 volatile bool 来控制线程执行 并且效果很好 in my class declaration volatile bool stop In the thread function while stop do th
  • Android 在通话期间播放音频文件[重复]

    这个问题在这里已经有答案了 对于我的 Android 应用程序 我想在从应用程序接听电话后播放音频文件 应用程序将发起电话呼叫 一旦接收者接听电话 应用程序应开始播放录制的音频文件 通过在谷歌上进行大量搜索 我发现这对于未root的设备来说
  • 如何使用 cf 程序查看我的 VCAP_SERVICES 环境变量?

    当我跑步时cf env
  • Zsh 中的鱼式自我暗示?

    有没有办法做到鱼的自我暗示类型 http ridiculousfish com shell images autosuggestion png in Zsh https github com tarruda zsh autosuggesti
  • 春季启动大战

    我倾向于在开发过程中使用可运行的 JAR 但我需要 WAR 来进行部署 我已经关注了this http spring io guides gs convert jar to war 有关从 JAR 转换为 WAR Spring Boot G
  • 如何使用 Javascript 从 Chrome iOS 下载 blob 文件?

    如何使用 Javascript 从 Chrome iOS 下载 blob 文件 我正在从 iOS 下载文件 pdf excel txt png iOS 没有文件系统 这对下载来说是一个问题 我创建了一个代码 根据操作系统和导航器 如果需要
  • 检测 perl 中声明的包变量

    Given package main our f sub f sub g 1 我怎样才能确定 f 但不是 g 已宣布 即兴的 我以为 main g SCALAR 可能是未定义的 但它是一个善意标量参考值 背景 我想将一个变量导入到main