簡體   English   中英

在其中調用proc時,ruby instance_eval的stac級別會太深

[英]ruby instance_eval will go stac level too deep when calling proc inside it

今天,我遇到了一個非常有趣的問題,紅寶石。 我有一個模塊/軌道關注:

module BreakCacheModule
  extend ActiveSupport::Concern      

  module ClassMethods
    def breakable_cache_for(method_name, &block)
      method_name = method_name.to_sym
      set_breakable_cache_proc(method_name, block)
      define_breakable_cache_method(method_name)
    end

    def define_breakable_cache_method(method_name) 
      instance_eval(
        "def #{method_name}
          # here will be Rails.cache.fetch block around line below once I figure out this problem
          @_break_cache_procs[#{method_name}].call  # !!! this line will cause an issue
        end"
      )
    end

    def set_breakable_cache_proc(method_name, block)
      @_break_cache_procs ||={}
      @_break_cache_procs.merge!({method_name => block})
      @_break_cache_procs
    end
  end

end

在我的模型中

class Client < ActiveRecord::Base
  include BreakCacheModule

  breakable_cache_for :all_client_ids do
    Client.pluck :id
  end
end

所以沙發很好,但是一旦我進入控制台(或運行我的規格),問題就會出現

Client.all_client_ids 
# SystemStackError: stack level too deep

但是當我這樣做時:

Client.instance_variable_get("@_break_cache_procs")[:all_client_ids].call
#=> [1,2,3]

功能完全相同,唯一的區別是我沒有從instance_eval調用proc。

我錯過了什么嗎?

我的紅寶石ruby-2.0.0-p247和Rails 3.2.14

謝謝你的幫助


接受后更新

總結一下,我實際上從兩個地方得到了這個錯誤:

    "def #{method_name}
      Rails.cache.fetch(#{method_name.to_s}) do     # method_name should be in quotes
        @_break_cache_procs[#{method_name}].call    # missing colon ...look on answer 
      end
    end"

所以代碼應該像這樣

  instance_eval(
    "def #{method_name}
      Rails.cache.fetch('#{method_name.to_s}') do
        @_break_cache_procs[:#{method_name}].call
      end
    end"
  )

傳遞給instance_eval的字符串實際上是:

"def all_client_ids
  @_break_cache_procs[all_client_ids].call
end"

您可能已經注意到了問題:缺少冒號。

這應該是正確的代碼:

def define_breakable_cache_method(method_name) 
  instance_eval(
    "def #{method_name}
      # here will be Rails.cache.fetch block around line below once I figure out this problem
      @_break_cache_procs[:#{method_name}].call  # !!! this line will cause an issue
    end"
  )
end

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM