rubyとrequire

2021-03-03

ruby

とあるrailsで、スクリプトファイルを require してて
これどうなるんだったっけかしら?mix-inとどっちが強い?
ムダに気になり始めてチェックしたときのメモ

先にまとめ

  • ルートに定義されたメソッドはKernelにプライベートメソッドとして生える
    なので XXX.hoge という呼び方では実行されない
    おもむろに hoge を呼ぶかsendを使う

  • サブクラス > モジュール > スーパークラス > ...と継承関係をたどって > Kernel

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
class Foo
  def foo
    puts 'foo_a'
  end
end

Foo.new.foo

begin
  Foo.new.bar
rescue
  puts $!.message
end

begin
  foo
rescue
  puts $!.message
end

puts Kernel.private_methods.any?{|m| m == :foo }
require_relative 'script_b'
puts Kernel.private_methods.any?{|m| m == :foo }

Foo.new.foo

begin
  foo
rescue
  puts $!.message
end

require_relative 'module_a.rb'

class Foo
  include ModuleA
end

Foo.new.foo

begin
  Foo.new.bar
rescue
  puts $!.message
end

class Bar < Foo
end

Bar.new.foo

require_relative 'module_b.rb'

class Bar < Foo
  include ModuleB
end

Bar.new.foo

class Bar < Foo
  def foo
    puts 'bar'
  end
end

Bar.new.foo
foo
1
2
3
4
5
def foo
  puts 'foo_b'
end

puts 'script_b'
1
2
3
4
5
6
7
8
9
module ModuleA
  def foo
    puts 'foo_module_a'
  end

  def bar
    puts 'bar_module_a'
  end
end

実行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ ruby script_a.rb
foo_a
undefined method `bar' for #<Foo:0x000056381987f800>      # <= Fooにbarはない
undefined local variable or method `foo' for main:Object  # <= 実行スコープ内にfooメソッドはない
false
script_b     # <= ロードしたscript_bが実行された
true         # <= Kernelに(private)fooが生えた
foo_a 
foo_b        # <= Kernel.foo
foo_a
bar_module_a # <= includeしたのでFooにbarが生えた
foo_a        # <= スーパークラスのfoo
foo_ModuleB  # <= moduleのfoo
bar          # <= サブクラスのfoo
foo_b        # <= カーネルは変わらない
  • ルートに定義されたメソッドはKernelにプライベートメソッドとして生える
    なので XXX.hoge という呼び方では実行されない
    おもむろに hoge を呼ぶかsendを使う

  • サブクラス > モジュール > スーパークラス > ...と継承関係をたどって > Kernel

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
require_relative 'hoge_module'

class Hoge
  include HogeModule
  def fuga
    wowwow
  end
end

Hoge.new.hoge

begin
  Hoge.new.wowwow
rescue
  puts $!.message
end

Hoge.new.send(:wowwow)

Hoge.new.fuga
1
2
3
4
5
6
7
8
9
10
module HogeModule
  def hoge
    puts 'hoge'
  end
end

# モジュールの外でwowwow
def wowwow
  puts 'wowwow'
end

実行

1
2
3
4
5
$ ruby hoge.rb
hoge
private method `wowwow' called for #<Hoge:0x00005580849dd2f8>
wowwow # <= sendなら呼べるの図
wowwow # <= おもむろにwowwowでも呼べるの図

github
オワリ

コメント

投稿する

投稿したコメントはご自身で削除できません

不適切なコメントと判断した場合は管理側で削除することがあります