LoginSignup
0
0

More than 1 year has passed since last update.

using Module.new ってなに?

Last updated at Posted at 2022-09-21

はじめに

調べ物をしている際に、using Module.new {}というコードを見たのでどういう処理をするんだろうと思い調べてみた備忘録です。

そもそも無名モジュールってなに?

無名モジュールは、その名の通り名前のついていないモジュールのことです。Module.newで作成したモジュールは無名モジュールとなるらしいです。
もちろん無名なので、includeなどで指定することが出来ませんので他のファイルから呼び出すこともできません、多分...。Mix-inすることできますね...(@scivolaありがとうございます)

mod = Module.new {
  def self.anonymous
    puts "anonymous module"
  end
}

mod.name
# => nil

mod.anonymous
# => anonymous module

MyClass = Class.new do
    include mod
end

MyClass.ancestors
# => [MyClass, #<Module:0x000001fb1163dc48>, Object, Kernel, BasicObject]

わざわざ無名で作成してるので、名前をつけたくなることがあるかは分かりませんが...
変数を参照することで名前を与えることができます。

mod = Module.new {
  def self.named
    puts "Named"
  end
}

Foo = mod

mod.name
# => Foo

Foo.named
# => Named

また、無名モジュールを返すメソッドを作成しincludeすることも可能です。

def anonymous_module(val)
  Module.new {
    define_method "#{val}" do
      puts "#{val}"
    end
  }
end


class MyClass
  include anonymous_module('hey')
end

MyClass.new.hey
# => hey

どのような時に使うのか?

タイトルから脱線していますが、そもそもusing Module.newはどのようにしようするのか?

クラス拡張をして他のファイルには影響を与えたくないときや、sendで外部から呼ばれたくないし、他のファイルでは使わないけどメソッドでまとめておきたい時に使用するらしいです。

例えば、String#reverseを書き換えたいけど、このファイルのみでしか使わないんだよなーってときに

anonymous.rb
using Module.new {
  refine String do
    def reverse
      "xxxx#{super}xxxx"
    end
  end
}

puts "abc".reverse
# => xxxxcbaxxxx

これで、String#reverseを書き換えることが出来ました。

ですが、先程のファイルを別ファイルに読込んでも拡張したString#reverseは使用することは出来ません。

other_file.rb
require './anonymous'

puts "abc".reverse
# => cba

んー他に使い方があるのかな...何かわかれば追記していきます。

参考文献

Rubyで、今いるファイルでだけヤンチャする機能
ksss/lib

0
0
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0