Rubyのdefの後に何を書けるか調べる実験

実務では一切の役に立たないRuby雑学。

普通のdef

まずは基本の書き方。

def foo
  puts "hello"
end

foo
#=> "hello"
class User
  def self.foo
    puts "foo"
  end

  class << self
    def bar
      puts "bar"
    end
  end
end

User.foo
#=> "foo"

User.bar
#=> "bar"

特異クラスの別の書き方

やってる事は同じだけど、selfをUserに変えたやつ。

class User
  class << User
    def bar
      puts "bar"
    end
  end
end

def User.foo
  puts "foo"
end


User.foo
#=> "foo"

User.bar
#=> "bar"

self以外のメソッド経由

class User
  def self.this
    User
  end

  def this.foo
    puts "foo"
  end
end

User.foo
#=> "foo"

インスタンスの特異メソッド

class User; end

user = User.new
def user.foo
  puts "foo"
end
user.foo
#=> "foo"

other = User.new
other.foo
#=> (NoMethodError)

.(ドット)を複数書く

シンタックスエラーになる。

# a.rb:1: syntax error, unexpected '.', expecting ';' or '\n'
def a.b.c

三項演算子

括弧で囲めば動く。

class User; end
class Admin; end

def (ENV.key?("CI") ? User : Admin).foo
  puts "foo"
end

Admin.foo
#=> "foo"

User.foo
#=> (NoMethodError)

Procの呼び出し

括弧で囲めば動く。

class A; end
find_class = -> { A }

def (find_class.call).foo
  puts "foo"
end
A.foo
#=> "foo"

リテラルを直置き

シンタックスエラーになる。

# a.rb:1: can't define singleton method for literals
def (1).foo
# a.rb:1: can't define singleton method for literals
def ("").foo
# a.rb:1: can't define singleton method for literals
def (:a).foo
# a.rb:1: can't define singleton method for literals
def ([]).foo

Hashのリテラルを括弧で囲む

おや...?

# no error
def ({}).foo
  puts "foo"
end

# 別インスタンスなのでメソッドは呼べない
{}.foo
#=> (NoMethodError)

Hashだけシンタックスエラーじゃないのは不思議。