【问题标题】:When you say Ruby is reflective, does this mainly refer to "duck typing"?当您说 Ruby 具有反射性时,这主要是指“鸭子打字”吗?
【发布时间】:2009-02-13 17:53:45
【问题描述】:

我正在阅读一篇描述 Ruby 的文字,它说:

Ruby 被认为是“反光” 语言,因为它是可能的 用于分析自身的 Ruby 程序(在 其构成),使 调整其工作方式,以及 甚至用其他代码覆盖自己的代码 代码。

我对“反射”这个术语感到困惑 - 这主要是在谈论 Ruby 可以查看变量并确定它是整数还是字符串(鸭子类型)的方式,例如:

x = 3
x = "three" # Ruby reassigns x to a String type

【问题讨论】:

  • 我想你也对“duck-typing”这个词感到困惑。它不是查看变量并确定其类型,而是以相同的方式处理响应特定方法的任何类型。例如 "123".size 和 [1,2,3].size - ...(继续下一条评论)
  • 所以,如果你创建一个像这样的方法 "def print_size(obj) puts obj.size; end" - 你传递一个字符串还是一个数组都没关系,它不会起作用类型很重要,因为两者都实现了“大小”。换句话说,他们都“嘎嘎”,所以他们一定是“鸭子”(这不是真的)——这就是 Ruby 的想法。

标签: ruby-on-rails ruby reflection duck-typing


【解决方案1】:

说 Ruby 是“反射性的”意味着你可以,例如,在运行时找出一个类有哪些方法:

>> Array.methods
=> ["inspect", "private_class_method", "const_missing",
[ ... and many more ... ]

(你可以对类的对象做同样的事情。)

或者你可以找出给定对象是什么类...

>> arr = Array.new
=> []
>> arr.class
=> Array

并找出它在类层次结构中是什么......

>> arr.kind_of?
>> arr.kind_of? Array
=> true
>> arr.kind_of? String
=> false

在他们所说的“Ruby 程序可以分析自己”的引文中,这就是他们所说的。

其他语言(例如 Java)也可以这样做,但使用 Ruby 时,它更容易、更方便,并且更多地成为使用该语言的日常部分。因此,Ruby 具有“反射性”。

【讨论】:

    【解决方案2】:

    不,这意味着您可以发出一个 ruby​​ 命令来获取关于任何东西的信息。例如,您可以键入命令 File.methods() 来获取属于 File 模块的所有方法的列表。你可以对类和对象做类似的事情——列出方法、变量等。

    【讨论】:

      【解决方案3】:

      班级重新开放就是一个很好的例子。这是一个简单的例子:

      class Integer
          def moxy
              if self.zero?
                  self - 2
              elsif self.nonzero?
                  self + 2          
              end      
          end  
      end
      
      puts 10.moxy
      

      通过重新打开一个标准的 Ruby 类 - Integer - 并在其中定义一个名为“moxy”的新方法,我们可以直接对数字执行新定义的操作。在这种情况下,我定义了这个由“moxy”组成的方法,如果它为零,则从整数中减去 2,如果它不为零,则添加 2。这使得 moxy 方法可用于 Ruby 中 Integer 类的所有对象。 (这里我们使用'self'关键字来获取整数对象的内容)。

      如您所见,这是 Ruby 的一个非常强大的特性。

      编辑:一些评论者质疑这是否真的是reflection。在英语中,反思一词是指审视自己的想法。这当然也是编程中反射的一个重要方面——使用诸如 is_a、kind_of、instance_of 之类的 Ruby 方法来执行运行时自检。但反射也指程序在运行时修改自身行为的能力。重开课程就是其中的关键例子之一。它也称为monkey patching。这并非没有风险,但我所做的只是在反思的背景下描述它,这是一个例子。

      【讨论】:

      • 绝对是一个强大的功能,但你确定这是反射的一个例子吗?我不知道严格来说,与自我合作是否是“反思”。我认为反射更像是在运行时询问类和对象以找出它们是什么以及它们可以做什么。
      • 是的,这并不是真正的反射功能,但仍然是一个很酷的功能。
      • 我了解您的困惑的根源。我将编辑我的回复,以解释我将重新开课作为反思的明确例子的理由。
      • 在上面的代码示例中,您重新打开“Integer”类以添加“moxy”方法,您是说“在运行时”这样做吗?我认为您对“运行时”定义的想法可能是错误的。
      • 我不是 Ruby 专家,但它没有 eval 函数吗?因此,您可以将其转换为字符串并在“运行时”运行。
      【解决方案4】:

      主要指在运行时检查和修改Ruby程序内部表示的难易程度,例如类、常量、方法等。

      大多数现代语言都提供了某种反射功能(甚至是静态类型的,如 Java),但在 Ruby 中,使用这些功能非常容易和自然,当您需要它们时,它确实会产生真正的影响。

      它只是让元编程,例如,一个几乎微不足道的任务,这在其他语言中根本不是这样,即使是动态语言。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-05-11
        • 2013-06-06
        • 1970-01-01
        • 2011-11-25
        • 1970-01-01
        • 2012-10-26
        • 2011-03-23
        • 2020-02-13
        相关资源
        最近更新 更多