- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
注意:我使用的是 Lua 5.3 版。
这个问题是由 Programming in Lua(第 4 版)的练习 25.1(第 264 页)提出的。该练习内容如下:
Exercise 25.1: Adapt
getvarvalue
(Listing 25.1) to work with different coroutines (like the functions from thedebug
library).
练习中引用的函数 getvarvalue
逐字复制如下。
-- Listing 25.1 (p. 256) of *Programming in Lua* (4th ed.)
function getvarvalue (name, level, isenv)
local value
local found = false
level = (level or 1) + 1
-- try local variables
for i = 1, math.huge do
local n, v = debug.getlocal(level, i)
if not n then break end
if n == name then
value = v
found = true
end
end
if found then return "local", value end
-- try non-local variables
local func = debug.getinfo(level, "f").func
for i = 1, math.huge do
local n, v = debug.getupvalue(func, i)
if not n then break end
if n == name then return "upvalue", v end
end
if isenv then return "noenv" end -- avoid loop
-- not found; get value from the environment
local _, env = getvarvalue("_ENV", level, true)
if env then
return "global", env[name]
else -- no _ENV available
return "noenv"
end
end
下面是我对该函数的增强版本,它实现了练习中指定的附加功能。这个版本接受一个可选的 thread
参数,应该是一个协程。此增强版本与原始 getvarvalue
之间的唯一区别是:
thread
参数;level
参数的特殊设置取决于thread
参数是否与正在运行的协程相同;和debug.getlocal
和 debug.getinfo
以及递归调用中传递 thread
参数。<(我在源代码中通过编号注释标出了这些差异。)
function getvarvalue_enhanced (thread, name, level, isenv)
-- 1
if type(thread) ~= "thread" then
-- (thread, name, level, isenv)
-- (name, level, isenv)
isenv = level
level = name
name = thread
thread = coroutine.running()
end
local value
local found = false
-- 2
level = level or 1
if thread == coroutine.running() then
level = level + 1
end
-- try local variables
for i = 1, math.huge do
local n, v = debug.getlocal(thread, level, i) -- 3
if not n then break end
if n == name then
value = v
found = true
end
end
if found then return "local", value end
-- try non-local variables
local func = debug.getinfo(thread, level, "f").func -- 3
for i = 1, math.huge do
local n, v = debug.getupvalue(func, i)
if not n then break end
if n == name then return "upvalue", v end
end
if isenv then return "noenv" end -- avoid loop
-- not found; get value from the environment
local _, env = getvarvalue_enhanced(thread, "_ENV", level, true) -- 3
if env then
return "global", env[name]
else
return "noenv"
end
end
这个函数工作得相当好,但我发现了一个奇怪的情况1,它失败了。下面的函数 make_nasty
生成一个协程,其中 getvarvalue_enhanced
找不到 _ENV
变量;即它返回 "noenv"
。 (作为 nasty
基础的函数是闭包 closure_B
,它又调用闭包 closure_A
。它是 closure_A
然后产生。)
function make_nasty ()
local function closure_A () coroutine.yield() end
local function closure_B ()
closure_A()
end
local thread = coroutine.create(closure_B)
coroutine.resume(thread)
return thread
end
nasty = make_nasty()
print(getvarvalue_enhanced(nasty, "_ENV", 2))
-- noenv
相比之下,几乎相同的函数 make_nice
生成一个协程,getvarvalue_enhanced
成功找到一个 _ENV
变量。
function make_nice ()
local function closure_A () coroutine.yield() end
local function closure_B ()
local _ = one_very_much_non_existent_global_variable -- only difference!
closure_A()
end
local thread = coroutine.create(closure_B)
coroutine.resume(thread)
return thread
end
nice = make_nice()
print(getvarvalue_enhanced(nice, "_ENV", 2))
-- upvalue table: 0x558a2633c930
make_nasty
和 make_nice
之间的唯一区别是,在后者中,闭包 closure_B
引用了一个不存在的全局变量(并且什么都不做)。
问: 我如何修改 getvarvalue_enhanced
以便它能够为 nasty
定位 _ENV
,它对 nice
的作用是什么?
编辑:更改了 make_nasty
和 make_nice
中闭包的名称。
EDIT2:练习 25.3(同一页)的措辞可能与此处相关(我强调):
Exercise 25.3: Write a version of
getvarvalue
(Listing 25.1) that returns a table with all variables that are visible at the calling function. (The returned table should not include environmental variables; instead it should inherit them from the original environment.)
这个问题意味着应该有一种方法可以从函数中获取仅仅可见的变量,无论函数是否使用它们。这样的变量肯定会包括 _ENV
。 (作者是Lua的创造者之一,所以他知道他在说什么。)
1 我敢肯定,对这个示例中发生的事情有更好理解的人将能够想出一种不太复杂的方法来引发相同的行为。我在这里展示的例子是我偶然发现的情况所能想到的最简单的形式。
最佳答案
local function inner_closure () coroutine.yield() end
local function outer_closure ()
inner_closure()
end
The function make_nasty below generates a coroutine for which getvarvalue_enhanced fails to find an _ENV variable; i.e. it returns "noenv"
这是正确的行为。
闭包 outer_closure
具有上值 inner_closure
但没有上值 _ENV
。
这就是词法作用域的工作原理。
一些闭包没有 _ENV
上值也没关系。
在您的示例中,闭包 inner_closure
未在 outer_closure
的主体内定义。inner_closure
未嵌套在 outer_closure
中。
关于debugging - 从协程内省(introspection) _ENV,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57161334/
Lua 从 setfenv() 切换有什么大不了的至 _ENV ? 在各种“新消息”来源中,这一举措被认为是 Lua 5.1 和 5.2 版本之间最重要的变化之一。 但是,PIL 和其他地方给出的示例
我正在运行Apache/2.2.11 (Win32) PHP/5.3.0我在 .htaccess 文件中执行了以下操作: SetEnv FOO bar 如果我打印出$_ENV PHP 文件中的变量,我
注意:我使用的是 Lua 5.3 版。 这个问题是由 Programming in Lua(第 4 版)的练习 25.1(第 264 页)提出的。该练习内容如下: Exercise 25.1: Ada
我正在运行 Apache/2.2.11 (Win32) PHP/5.3.0,我在 .htaccess 文件中执行了以下操作: SetEnv FOO bar 如果我在 PHP 文件中打印出 $_ENV
在我的项目中,我正在执行 XML 文件中包含的一些 lua 函数。我从 C++ 读取 XML,解析代码字符串,执行它们并获得结果。我发现的所有相关问题要么使用专用的 .lua 文件,要么直接在 Lua
我对超全局数组 $_ENV 和 $_SERVER 的理解是否正确? $_ENV: Contains information about environment variables $_SERVER:
通过 $_ENV 变量在您自己的代码中使用 .env 文件中的参数是否正常?当然是在使用 Symfony 4 的项目上下文中。 我有这样的代码: //WebhookUrlBuilder.php cla
我目前正在学习如何使用 Lua C API,虽然我已经成功在 C/C++ 和 Lua 之间绑定(bind)函数,但我有几个问题: 将多个脚本加载到单个 lua_State 中是个好主意吗?有没有办法关
我正在用 Ruby 编写一个小的 CGI 脚本,用于记录访问者的数据。我想记录所有 CGI 环境变量,如 REMOTE_ADDR、USER_AGENT、HTTP_REFERER 等。在 PHP 中遍历
在我的 PHP 代码中,我试图访问我在/etc/profile 中导出的 linux 系统环境变量。 当我在终端中键入“printenv”时,我可以看到设置了变量(称为 MEMCACHED_1)。 但
大多数情况下,我使用过$_SESSION,但是在阅读有关 Session 的内容时,我得到的术语很少 $_ENV & $_COOKIE。 我不清楚什么时候使用哪个,我对我可以使用它们的情况感到困惑。那
getenv() 和 $_ENV 有什么区别? 使用两者之间有什么权衡吗? 我注意到有时 getenv() 可以满足我的需要,而 $_ENV 却不能(例如 HOME)。 最佳答案 根据the php
在使用 GitHub 操作时,我在 $_ENV('ENV') 中遇到 undefined index 错误,但是当我使用 getenv('ENV') 时,我实际上得到了变量我在找。我该如何解决? 最佳
我想为我的数据库凭证使用 Laravel 环境,我这样做了: 在 bootstrap\start.php 中: $env = $app->detectEnvironment(array( 'local
我正在从 CLI 界面运行 PHP 脚本。 我怎样才能像在 Apache 中一样获取运行用户名 ($_ENV['APACHE_RUN_USER'])?现在我正在使用 exec('whoami'),但不
我正在使用 Laravel 5.3 测试我的系统: 在过去的几周里,我的系统运行良好。自上周末以来,我遇到了如下相同的错误 TWICE:- Notice: Undefined variable: _E
当 print(_ENV) 在 windows 上的 zerobrane studio 中使用时,结果为 nil。我们可以将 _ENV 变量设置为预期用途吗?作为代码示例, a = 15
在 apache 环境中 setenv 相当于什么?例如,使用 apache,我可以设置环境“SOMEENV”并通过 $_ENV['SOMEENV'] 在 php 中访问它 - 但我不知道如何
我在 Joomla 中遇到这个错误: Illegal variable `_files` or `_env` or `_get` or `_post` or `_cookie` or `_server
我是一名优秀的程序员,十分优秀!