为什么回调在Ruby on Rails中使用符号

时间:2014-11-06 18:15:59

标签: ruby-on-rails ruby callback symbols

我很难理解何时何时不在Rails中使用符号。我知道符号与没有很多方法的字符串差别太大。我也理解这些符号是好的密钥,因为同名的符号占用了内存中的一个地址。

我很难理解为什么Rails决定在某些情况下使用符号。如果我有回调

before_action :ask_stack_overflow_question

def ask_stack_overflow_question
  puts "why did I just use a symbol?"
end

我不太明白为什么把方法视为一种符号?为什么我需要保持方法不变?

我在文档中找不到任何答案。

谢谢

4 个答案:

答案 0 :(得分:8)

这并不像看起来那么棘手。

调用before_action时,您不希望立即执行该方法,但您必须以某种方式描述您想要执行的操作。此处使用符号表示要调用的方法的名称

因此,如果将其捕获为name,稍后在代码中的某处,则会在适当的时间将其转换为send(name)

这两者之间存在很大差异。直接版本是:

before_action method_name

这会立即执行method_name,因为Ruby将被迫运行method_name以找出它返回的内容,然后将其作为参数传递给before_action。< / p>

延期惯例是:

before_action :method_name

这只是对before_action的礼貌请求,传递符号作为参数。你将它留给before_action来处理这个问题然而它认为合适,所以它可能会或者可能不会在将来执行该方法,这取决于具体情况。

这是在Ruby中使用非常几个例外的方式。我唯一可以想到的是,当它立即指定而不是作为代表性符号时,立即执行一个方法就是古怪的alias构造。

答案 1 :(得分:1)

如果你read this code which defines before_action on the second line

[:before, :after, :around].each do |callback|
    define_method "#{callback}_action" do |*names, &blk|
      _insert_callbacks(names, blk) do |name, options|
        set_callback(:process_action, callback, name, options)
      end
    end

在调用方法时调用set_callback method here的调用get_callback method。这会创建一个回调链。这个回调链形成here,后来由this method用于执行。现在,您可以传递字符串或作为符号。但是,首选方法是传递符号,因为它们是不可变的,并且在执行过程中不能被更改。

答案 2 :(得分:1)

Ruby符号是立即值。关于符号的重要事项是符号本身。因此,在某事物的身份很重要的地方,您可以使用符号。

内存方面,它是永久性的(在程序运行期间),是不可变的,始终是同一个对象。

字符串在Ruby中没有这种奢侈品。 “this string”和“this string”将是两个独立的对象,并受垃圾回收。

:this_symbol不受垃圾回收的影响,总是相同的对象,因此内存效率很高。符号可以引用名称this_symbol的局部变量或名称this_symbol或任何其他命名对象的方法,但可以由完全相同的对象引用,即:this_symbol。

何时不使用符号?当你需要暂时使用其中许多,一次或几次使用时,在一个长时间运行的程序中最终将填满内存,没有希望恢复该内存供其他用途。

因此,他们并没有真正使用符号作为方法,但Ruby确实通过符号引用方法名称。我认为更改的方法名称不会像保持不变的方法名称一样有用。

答案 3 :(得分:0)

这是引用某些东西最便宜的方式,然后符号才有意义。

通常有可能不使用符号:

before_action do
  # do something
end

但是通过这种方式,您将无法重复使用该方法,以防万一。你也可能会失去一些表现力。

在我看来,这两个选项都是正确的,无论您选择哪个选项,重要的是您的代码是可读的而不是多余的。