對於Ruby 1.9.2,我使用class_eval來擴展類。從class_eval'ed方法返回數組時出現的奇怪行爲
def slugged(fields)
# assign string to variable only for easier debugging
method = <<-EOS
def slug_fields
#{ fields.is_a?(Array) ? fields.inspect : ":#{ fields }" }
end
EOS
class_eval method
end
此只要能正常工作作爲字段是符號(例如後slugged :name
,slug_fields
:name
返回)。
但是,調用slugged
以與陣列使得slug_fields
nil
返回(例如後slugged [:kicker, :headline]
,slug_fields
nil
返回)。
奇怪的是,調試slugged
時,含待創建方法的字符串看起來完全相同的方式,你會期望他們:
" def slug_fields\n [:kicker, :headline]\n end\n"
" def slug_fields\n :name\n end\n"
編輯:根據要求,對什麼打破了更完整版我:
module Extensions
module Slugged
extend ActiveSupport::Concern
included do
before_validation { |record| record.slug ||= record.sluggerize }
end
module ClassMethods
def slugged(fields)
# assign string to variable only for easier debugging
method = <<-EOS
def slug_fields
#{ fields.is_a?(Array) ? fields.inspect : ":#{ fields }" }
end
EOS
class_eval method
end
end
module InstanceMethods
def sluggerize
fields = slug_fields
slug_string = case
when fields.is_a?(Array)
fields.map { |f| self.send(f) }.join('-')
else
self.send fields
end
slug_string.parameterize
end
end
end
end
class Article < ActiveRecord::Base
include Extensions::Slugged
slugged [:kicker, :headline]
end
class Station < ActiveRecord::Base
include Extensions::Slugged
slugged :name
end
a = Article.new :headline => "this is a great headline!", :kicker => "attention-drawing kicker"
a.save # works, slug is set
s = Station.new :name => "Great Music"
s.save # TypeError: nil is not a symbol (in sluggerize where "self.send fields" is called)
確實很奇怪。你有嘗試過使用'class_exec'嗎? http://ruby-doc.org/core-1.8.7/classes/Module.html#M000187 –