I run into really interesting problem with ruby today. I have a module/rails concern :
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
and in my model
class Client < ActiveRecord::Base
include BreakCacheModule
breakable_cache_for :all_client_ids do
Client.pluck :id
end
end
so sofar so good but once I go into console (Or run my spec) problems will show up
Client.all_client_ids
# SystemStackError: stack level too deep
but when I do:
Client.instance_variable_get("@_break_cache_procs")[:all_client_ids].call
#=> [1,2,3]
The functionality is exactly the same, only difference is that I'm not calling proc from instance_eval.
Am I missing something ??
my ruby ruby-2.0.0-p247 and Rails 3.2.14
Thank you for help
Update after accepting
Just to sum this up, I was getting actually this error from two places:
"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"
so the code should look like this
instance_eval(
"def #{method_name}
Rails.cache.fetch('#{method_name.to_s}') do
@_break_cache_procs[:#{method_name}].call
end
end"
)
The string passed to instance_eval
is actually:
"def all_client_ids
@_break_cache_procs[all_client_ids].call
end"
You may have noticed the problem: a colon is missing.
This should be the correct code:
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
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.