我是 ruby?? 的新手,開始學習這種語言的元編程技術。現在我正在嘗試撰寫一個 DSL 模塊來注釋 RoR 中的類。不幸的是,我仍然沒有得到關于這個主題的一些東西,這會在實作中造成一些麻煩。
這是標簽注釋的代碼示例:
module Annotations
def self.included(host_class)
host_class.extend(ClassMethods)
end
def tags(*values)
if values.empty?
if defined? @tags
@tags
else
self.class.tags(values)
end
else
@tags = []
values.map { |value| validate_tag(value) }.each { |tag| @tags << tag}
end
end
module ClassMethods
def tags(*values)
unless defined? @tags
superclass_tags = self.superclass.tags if self.superclass.respond_to?(:tags)
@tags = superclass_tags&.any? ? superclass_tags : []
end
if values.empty?
@tags
else
if self.superclass.respond_to?(:tags)
values.map { |value| validate_tag(value) }.each { |tag| @tags << tag}
else
@tags = values.map { |value| validate_tag(value) }
end
@tags
end
end
alias_method :tag, :tags
def validate_tag(tag)
raise 'Tag should be less than 15 chars.' if tag.to_s.length > 15
end
end
end
class Foo
include Annotations
tags :x1, :x2
end
當我嘗試執行它時,它將始終是相同的錯誤輸出。
Foo.tags
=> [nil, nil]
Foo.tag 'c'
Foo.tags
=> [nil]
foo2 = Foo.new
foo2.tags :c5, :c9
foo2.tags
=> [nil, nil]
# etc...
你能幫我改進代碼/讓我明白我在哪里犯了錯誤嗎?
uj5u.com熱心網友回復:
唯一的問題在于你的validate_tag方法。守衛正在檢查作為字串的標記的長度是否大于 15,如果發生這種情況,則會引發例外,但是當這種情況不發生時,沒有明確添加值。在這種情況下,Ruby 回傳 nil。
如果tag.to_s.length > 15回傳 false,您可以嘗試更新它以回傳標簽:
def validate_tag(tag)
raise 'Tag should be less than 15 chars.' if tag.to_s.length > 15
tag
end
uj5u.com熱心網友回復:
您的validate_tag方法不回傳tag,但您正在映射您的values引數tags并呼叫validate_tag(value),將陣列轉換[:foo, :bar]為[nil, nil]。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/418361.html
標籤:
下一篇:向哈希陣列添加新鍵
