在 child 中使用 lambda/Proc class 在 ruby 中使用
Use lambda/Proc in child class in ruby
如何使用或引用 base/super class 中定义的 lambda?
超class码
module Api
class ApplicationSerializer
include JSONAPI::Serializer
# I Also tried it this way
# serializer_for_proc = -> (object) { SerializerLookup.new.(object) }
def serializer_for_proc
-> (object) { SerializerLookup.new.(object) }
end
end
end
Childclass代码
module Api
class AnswerSerializer < ApplicationSerializer
attributes :values, :created_at, :updated_at, :usage
belongs_to :question, serializer: serializer_for_proc # NameError (undefined local variable or method `serializer_for_proc'
end
end
如前所述,serializer_for_proc
是 Api::ApplicationSerializer 的实例方法,但您试图直接在 class 上调用它(或者更确切地说,直接在子 class).换句话说,以下所有失败的原因或多或少是相同的:
belongs_to :question, serializer: serializer_for_proc
belongs_to :question, serializer: ApplicationSerializer.serializer_for_proc
belongs_to :question, serializer: AnswerSerializer.serializer_for_proc
您实际上从未定义过 ApplicationSerializer.serializer_for_proc
,您已经定义了传统上写为 ApplicationSerializer#serializer_for_proc
的内容,换句话说,ApplicationSerailizer.new.serializer_for_proc
.
解决此问题的最快方法是将原始方法定义设为 class 方法:
module Api
class ApplicationSerializer
include JSONAPI::Serializer
def self.serializer_for_proc
-> (object) { SerializerLookup.new.(object) }
end
end
end
您在评论中写道,当您将它复制到 AnswerSerializer 文件中时,确实 起作用,但这不太可能(基本上不可能)。 的工作是将 serializer_for_proc = -> (object) { SerializerLookup.new.(object) }
版本复制到 AnswerSerializer 文件中,因为那时 serializer_for_proc
根本不是方法名称,它只是内部的一个局部变量AnswerSerializer
文件,与 x = 5
相同。但那是不可继承的。
另一种解决方案(尽管我不太喜欢)是使 serializer_for_proc
成为常数,例如:
# One file
module Api
class ApplicationSerializer
include JSONAPI::Serializer
SERIALIZER_FOR_PROC = -> (object) { SerializerLookup.new.(object) }
end
end
# Another file
module Api
class AnswerSerializer < ApplicationSerializer
attributes :values, :created_at, :updated_at, :usage
belongs_to :question, serializer: SERIALIZER_FOR_PROC
end
end
这行得通,但我不喜欢依赖它,因为 Ruby 中基于继承的常量查找有一些 pretty weird edge cases。如果我想使用常量,我个人只会使用 Api::ApplicationSerializer::SERIALIZER_FOR_PROC
。
如何使用或引用 base/super class 中定义的 lambda?
超class码
module Api
class ApplicationSerializer
include JSONAPI::Serializer
# I Also tried it this way
# serializer_for_proc = -> (object) { SerializerLookup.new.(object) }
def serializer_for_proc
-> (object) { SerializerLookup.new.(object) }
end
end
end
Childclass代码
module Api
class AnswerSerializer < ApplicationSerializer
attributes :values, :created_at, :updated_at, :usage
belongs_to :question, serializer: serializer_for_proc # NameError (undefined local variable or method `serializer_for_proc'
end
end
如前所述,serializer_for_proc
是 Api::ApplicationSerializer 的实例方法,但您试图直接在 class 上调用它(或者更确切地说,直接在子 class).换句话说,以下所有失败的原因或多或少是相同的:
belongs_to :question, serializer: serializer_for_proc
belongs_to :question, serializer: ApplicationSerializer.serializer_for_proc
belongs_to :question, serializer: AnswerSerializer.serializer_for_proc
您实际上从未定义过 ApplicationSerializer.serializer_for_proc
,您已经定义了传统上写为 ApplicationSerializer#serializer_for_proc
的内容,换句话说,ApplicationSerailizer.new.serializer_for_proc
.
解决此问题的最快方法是将原始方法定义设为 class 方法:
module Api
class ApplicationSerializer
include JSONAPI::Serializer
def self.serializer_for_proc
-> (object) { SerializerLookup.new.(object) }
end
end
end
您在评论中写道,当您将它复制到 AnswerSerializer 文件中时,确实 起作用,但这不太可能(基本上不可能)。 的工作是将 serializer_for_proc = -> (object) { SerializerLookup.new.(object) }
版本复制到 AnswerSerializer 文件中,因为那时 serializer_for_proc
根本不是方法名称,它只是内部的一个局部变量AnswerSerializer
文件,与 x = 5
相同。但那是不可继承的。
另一种解决方案(尽管我不太喜欢)是使 serializer_for_proc
成为常数,例如:
# One file
module Api
class ApplicationSerializer
include JSONAPI::Serializer
SERIALIZER_FOR_PROC = -> (object) { SerializerLookup.new.(object) }
end
end
# Another file
module Api
class AnswerSerializer < ApplicationSerializer
attributes :values, :created_at, :updated_at, :usage
belongs_to :question, serializer: SERIALIZER_FOR_PROC
end
end
这行得通,但我不喜欢依赖它,因为 Ruby 中基于继承的常量查找有一些 pretty weird edge cases。如果我想使用常量,我个人只会使用 Api::ApplicationSerializer::SERIALIZER_FOR_PROC
。