ruby-on-rails - 关于 Symbol 对象的 Ruby 文档具有误导性

标签 ruby-on-rails ruby symbols

我是 Ruby 的新手,和其他人一样,我无法理解 Ruby 符号。我知道这个主题已被多次提及,但我相信这篇文章可能与其他文章略有不同。如果没有,我很抱歉。以 documentation 中的这段代码为例.

module One
  class Fred
  end
  $f1 = :Fred
end
module Two
  Fred = 1
  $f2 = :Fred
end
def Fred()
end
$f3 = :Fred
$f1.object_id   #=> 2514190
$f2.object_id   #=> 2514190
$f3.object_id   #=> 2514190

我的提示是,它让我们认为类、模块或函数与 :Fred 符号之间存在联系。难怪人们会问“我可以为符号赋值吗”或者符号是对另一事物的引用。

这段代码增加了困惑:

class TestController < ApplicationController

    layout :which_layout

    def index
        ...
    end

    private

    def which_layout
        if condition
            "layout1"
        else
            "layout2"
        end
    end
end

起初,我以为是对函数的引用,但实际上这只是 layout 的行为方法将根据我们是否传递 String(模板名称)或 Symbol(调用由该符号指定的方法)而有所不同,如文档所述。 (它是否寻找与我们作为参数传递的符号等效的 method.to_sym?)

但是我相信我读到的是,当创建一个类时,他的符号对应物将被自动创建,即 :Fred 将已经存在于后续调用中。但仅此而已?

我的问题是:为什么他们必须包含一个类、一个变量和一个函数来说明这一点?上下文?那为什么要同名呢?为什么不这样做:

$f1 = :Fred
$f2 = :Fred
$f3 = :Fred

$f1.object_id   #=> 2514190
$f2.object_id   #=> 2514190
$f3.object_id   #=> 2514190

最佳答案

当您使用一个符号时,Ruby 会查看现有符号的列表,因此当您重用一个符号时,您不会在内存中创建一个单独的对象。

irb(main):006:0> :foo.object_id == :foo.object_id
=> true

您可以将其与字符串进行对比:

irb(main):007:0> "foo".object_id == "foo".object_id
=> false

再加上它们比较便宜的事实,使得符号像散列键一样有效。

这个非常令人困惑的例子表明,符号不是范围私有(private)的——符号表是全局的。如果使用实例变量而不是全局变量,那么混淆会少一些。我认为它还试图证明模块和类名称是常量。

irb(main):016:0> Fred = Module.new do; end # this is the same as using the module keyword
irb(main):017:0> Fred.object_id != :Fred.object_id
=> true

这意味着 Fred 是对模块的引用,而 :Fred 是一个值(一个符号)。

像字符串这样的符号是一个值,因此不能用作引用。这与 truefalsenil 非常相似,它们都是单例对象。

irb(main):008:0> true.class
=> TrueClass
irb(main):09:0> true.object_id == true.object_id
=> true
# you can even use the singletons as hash keys
irb(main):010:0> { true => 1, false => 2, nil => 3 }[true]
=> 1

Rails 示例并没有那么复杂。 :which_layout 只是传递给布局方法的参数。布局方法有一个条件,它使用 Object#send 动态调用 :which_layout 方法(如果存在)。而是直接使用字符串参数来构造一个 glob。

关于ruby-on-rails - 关于 Symbol 对象的 Ruby 文档具有误导性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57363267/

相关文章:

ruby-on-rails - 使用 will_paginate 从 Rails 查询中获取总结果计数

ruby-on-rails - rails + Postgres : How to select count of how many records are updated or inserted?

html - 所选数据(静态选择框)在编辑 View 中不显示

ruby-on-rails - KeyBoard 停止在 RubyMine IDE 上工作

ruby-on-rails - Rails Bundler gems 安装

ruby - 缺少 mysql2 gem。将它添加到你的 Gemfile : gem 'mysql2'

ruby - 尝试从多个哈希创建深度为 3 的哈希

linker - "Local Linker Symbols"和 "Local Program Variables"有什么区别?

javascript - 这个片段中的这个是什么?

XCode:当前类的更好的符号导航器