使用 $& 全局变量的编程别名方法

2024-03-31

我正在尝试给一个使用 Ruby 特殊方法的方法起别名$& (返回最后一个正则表达式匹配 http://jimneath.org/2010/01/04/cryptic-ruby-global-variables-and-their-meanings.html#_dollar_ampersand)。我可以手动执行此操作并且有效:

original = String.instance_method(:sub)
String.send(:define_method, :sub) do |*args, &block|
  puts "called"
  original.bind(self).call(*args, &block)
end
"foo".sub(/f/) { $&.upcase }
  called
  # => "Foo"

但是,如果我尝试编写一个为我执行此操作的方法,则会失败:

def programatic_alias(klass, method_name)
  original = klass.instance_method(method_name)
  klass.send(:define_method, method_name) do |*args, &block|
    puts "called"
    original.bind(self).call(*args, &block)
  end
end

programatic_alias(String, :sub)
"foo".sub(/f/) { $&.upcase }
  called
  NoMethodError: undefined method `upcase' for nil:NilClass
  called
  called
  called
    from (irb):19:in `block in irb_binding'

看起来全局状态正在受到范围的影响programatic_alias方法,但我不确定这是否是发生的事情。问题是这样的:我如何以编程方式别名String#sub这样它仍然可以与 Ruby 的特殊全局变量一起使用吗?


据我所知,你不能这样做。这docs http://ruby-doc.org/core-2.2.0/Regexp.html say

这些全局变量是线程局部变量和方法局部变量。

如果你深入研究 ruby​​ 源代码,访问$& calls last_match_getter https://github.com/ruby/ruby/blob/ruby_2_2/re.c#L1643它的数据来自rb_backref_get https://github.com/ruby/ruby/blob/ruby_2_2/vm.c#L944,这称为vm_svar_get https://github.com/ruby/ruby/blob/ruby_2_2/vm.c#L930它(跳过一些内部方法)获取当前控制帧并从那里读取数据。这些数据都不会暴露给 ruby​​ api - 无法将这些数据从一帧传播到您想要访问它的帧。

在您的第二个示例中,对原始方法的调用发生在您的内部programatic_alias方法等$&正在该范围内设置。为了同样的原因

'foo'.try(:sub, /f/) {$&.upcase}

也行不通。

你的第一个例子有效,因为这个地方sub被称为和地方$&被引用(在块内)位于相同的方法范围内(在本例中为 ruby​​ 顶级)。将其更改为:

original = String.instance_method(:sub)
String.send(:define_method, :sub) do |*args, &block|
  puts "called"
  original.bind(self).call(*args, &block)
end

def x
  "foo".sub(/f/) { $&.upcase }
end

x()

and $&不再在您的块中定义(如果您捕获由x你可以看到$&正在设置在顶层)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 $& 全局变量的编程别名方法 的相关文章

随机推荐

  • 三星 Galaxy S II AVD(Android 虚拟设备)基本设置?

    我想创建 Samsung Galaxy S II 的 AVD 唯一的目的是使用默认的网络浏览器测试网站 看看它们在纵向和横向模式下的外观如何 由于它是现在最受欢迎的 Android 智能手机 我想通过我的网站对其进行测试 我只想知道最基本的
  • Android EditText下一个焦点

    我有几个 EditTexts 分布在 2 个片段中 其中一个片段具有以下 xml 布局
  • 在 Owin、Katana 和 Nancy 中成功进行 cookie 身份验证后重定向到 ReturnUrl

    我正在使用 Owin Katana 和 Nancy 托管一个带有需要身份验证部分的简单站点 注意我也使用 nuget 包 Nancy MSOwinSecurity app UseCookieAuthentication new Cookie
  • 如何用R代码编织Rmd文件生成word文档

    我已经创建了一个 Rmd 文件 并且我知道如果我转到工具栏并选择 knit to word 它将为我生成一个 Word 文档 我的问题是如何使用 R 代码执行此操作 而无需实际单击顶部工具栏上的 knit to word 选项 我有这段代码
  • 如何使用带有空格的命令名称?

    当 python bot 中的命令之间有空格时 如何使 bot 工作 我知道我们可以使用子命令或on message但是是否还有其他选项可以仅对选定的命令而不是对所有命令执行此操作 下面的代码将不起作用 bot command pass c
  • Java - 按步骤切片任何数组

    在 python 中 我们可以执行以下操作 array 0 1 2 3 4 5 6 7 8 9 10 new array array 3 print new array gt gt gt 0 3 6 9 Java中有类似的东西吗 我一直在寻
  • 朱莉娅中的矢量化“in”函数?

    我经常想要循环遍历数据帧的长数组或列 并且对于每个项目 查看它是否是另一个数组的成员 而不是做 giant list a c j good letters a b isin falses size giant list 1 for i 1
  • 如何一次推送单个docker镜像层?

    我已经开始推送新的镜像 场景是这样的 b57ecdb750f2 Pushing gt 43 57MB 473 9MB 9b7e4da6c261 Pushing gt 18 94kB 21d523b40367 Pushed e18c77c6a
  • TCP/IP 消息帧

    我制作了一个 TCP IP 服务器 客户端 它是异步的 但它连接了消息 如何正确地在开头添加标头 然后在末尾使用字符串生成器来取消连接完整消息 服务器读取消息 Private Sub ReadCallback ByVal result As
  • 在 componentDidMount 中导航-react-router-dom v6

    这是我第一次使用react router dom v6 我对v4很熟悉 我有一个电影列表 每部电影都有一个 id 如果用户在 url 中输入了错误的电影 id 我需要导航到未找到的页面 我使用类组件的问题所以我坚持使用 componentD
  • R - 通过多个 URL 进行网页抓取?带着 rvest 和 purrr

    我正在尝试为我正在从事的项目抓取足球统计数据 并且我正在尝试利用 rvest 和 purrr 来循环遍历 url 末尾的数值 我不确定我错过了什么 但我有一段代码以及不断出现的错误消息 library xml2 library rvest
  • WPF c# .net 框架 4.8 x:绑定

    我读到x Bind 它比Binding 但是在我的应用程序 WPF C 和 NET Framework 4 8 中 当我把x Bind在任何部分 TextBox Text x Bind Visual Studio 对我说 Windows P
  • 随机数:0或1

    我是不是看得太远了 看不到像选择一个数字 0 或 1 这样简单的事情 Random rand new Random if rand NextDouble 0 lnkEvents CssClass selected else lnkNews
  • 创建动态匿名类型变量

    我可以创建一个匿名类型变量 然后添加更多属性吗 E g var x new Name Ahmed 并想添加Age到它 我怎样才能做到这一点 另一个问题 我在一些博客上看到一种类型AnonymousType这个类的名称空间是什么 这是例子ht
  • 自定义 CKEditor 工具栏

    我想自定义CKEditor的工具栏 不过 首先我想要一个工具栏可用选项的完整列表 我搜索了工具栏选项并发现了以下不完整列表 请帮我找到完整的列表 以便我可以根据我的要求进行选择 config toolbar MyToolbar name d
  • 寻找一种算法(二维二分查找的版本)

    简单的问题和已知的算法 我有一个有 100 名成员的大数组 前 X 个成员为 0 其余为 1 找到 X 我通过二分查找来解决这个问题 检查成员 50 如果它是 0 检查成员 75 等等 直到找到相邻的 0 和 1 我正在寻找针对二维相同问题
  • 将 ArrayBuffer 响应转换为 JSON

    在这里 我调用 GetFile 以 ArrayBuffer 对象的形式获取响应 如果我执行 response errors undefined 则在网络选项卡中响应为 errors photoProof Image is not avail
  • 在 postgres 查询中使用 ANY 时,有没有办法保留顺序或数组?

    我希望能够使用进行查询ANY它维护传递给 any 函数的数组的顺序 考虑这个简单的例子 create table stuff id serial value int insert into stuff value values 1 2 3
  • QProgressBar不显示进度?

    我在更新进度条时的第一个天真的做法是在正在进行处理的循环中包含以下几行 制作如下内容 while data hasMoreItems doSomeProcessing data nextItem Added these lines but
  • 使用 $& 全局变量的编程别名方法

    我正在尝试给一个使用 Ruby 特殊方法的方法起别名 返回最后一个正则表达式匹配 http jimneath org 2010 01 04 cryptic ruby global variables and their meanings h