【问题标题】:How do string literals in ruby bypass new/initialize, and is there a way to instrument this?ruby 中的字符串文字如何绕过 new/initialize,有没有办法对此进行检测?
【发布时间】:2023-03-13 18:30:01
【问题描述】:

今天下午我在玩一个想法,偶然发现了一些我不太理解的东西。基本上,我在这个实验中想要实现的目标是以某种方式知道每次创建字符串时(供以后使用,例如在某种 DSL 中)。以下适用于通过 String.new 创建的任何字符串:

class ::String
  class << self
    alias_method :new_orig, :new
    def new(*args)
      o = new_orig(*args)
      puts "newing '#{o}'"
      o
    end
  end
  alias_method :initialize_orig, :initialize
  def initialize(*args)
    initialize_orig(*args)
    puts "initializing '#{self}'"
  end
end

例如

irb > String.new("foo")
initializing 'foo'
newing 'foo'
 => "foo"

我想不通的是,当您使用文字时如何创建 String 对象。例如,为什么这不经过相同的初始化和设置:

irb > "literal string"
 => "literal string"

我意识到当字符串是文字时编译器正在做一些不同的事情,但它不需要初始化,只是为了成为一个功能齐全的对象吗?是否有任何技巧可以用来确定何时使用文字创建字符串,或者这是不可能的?

谢谢!

【问题讨论】:

  • 如果这确实有效,您将获得一个无限循环,因为您的这些方法版本本身会创建新的 Strings 以传递给 puts
  • 我的五分钱,想知道对象的历史是违反 OOP 原则的。
  • 啊,即使是无限循环,至少也会告诉我更多关于内部发生的事情,现在我不知道这些对象是如何创建的......另外,这个实验不是要编写完美的 OOP 代码,而是要测试语言可以做些什么来获得一些乐趣和学习新东西的界限。 :)
  • 有一种discussion与此相关,这导致了对bug/fix的讨论。
  • 在试图找出 OP 要求的相同内容时发现了这个线程。这里有一些有用的信息:bugs.ruby-lang.org/issues/4893

标签: ruby internals


【解决方案1】:

我认为,从接下来的讨论来看,这里几乎没有人会给你真正的答案,除非 Chris Heald 醒来并真正按照他的承诺查看源代码。但是,如果,正如您在对问题的评论中所说,目的是“测试语言可以做些什么来获得一些乐趣和学习新东西的界限”,那么让我向您介绍 - 尽管我讨厌 SlideShare - this Ruby presentation by famous esoteric programmer Yusuke Endoh.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-10
    • 2010-11-14
    • 2021-01-04
    • 1970-01-01
    • 2011-11-29
    • 1970-01-01
    相关资源
    最近更新 更多