クラスまたはモジュールでプライベート メソッドを呼び出さずに送信する
概要
ここで何が間違っているのかわかりません。クラスまたはモジュールを作成して、そのクラス/モジュール内のプライベート メソッドを呼び出すために使用できるようにしようとしています。
次のエラーが発生します: NoMethodError (MixPanelService:Class の未定義メソッド ‘call’)
MixPanelService.call(shop, “install”) を実行しようとすると
私の簡略化したコードは次のとおりです。
class MixPanelService
def call(shop, event_type)
send(event_type, shop)
end
private
def install
ap "do something"
end
end
そこでモジュールを試してみたところ、次のエラーが発生しました。 NoMethodError (MixPanelService:Module の未定義メソッド「install」)
基本的に同じことを試してみると: MixPanelService.call(ショップ, “インストール”)
次のコードを使用します。
module MixPanelService
module_function
def call(shop, event_type)
send(event_type, shop)
end
private
def install
ap "do something"
end
end
私の何が間違っているのでしょうか?
解決策
クラスでは呼び出しをインスタンス メソッドとして定義しましたが、クラス メソッドとして呼び出しています。 def self.call を使用してクラスメソッドにすることができます。
class MixPanelService
def self.call(shop, event_type)
send(event_type, shop)
end
def self.install(shop)
# do something
end
private_class_method :install # ugly :(
end
# Call it like this:
MixPanelService.call(shop, 'install')
ただし、それは最良のデザインではありません。クラスメソッドを使用して引数を渡すのは面倒です。インスタンスを操作できますが、すべてを実行するためのクラス メソッドもあります。このパターンを見てください。
class MixPanelService
def self.call(shop, event_type)
new(shop).call(event_type)
end
def initialize(shop)
@shop = shop
end
def call(event_type)
send(event_type)
end
private
def install
# Install something on `@shop`. Since it's an instance variable,
# we don't need to pass it around via params! :)
end
end
# Call it the same way as before:
MixPanelService.call(shop, 'install')