最初のは yield での処理、その後は Proc オブジェクトに変換しての処理です。
class Foo
def self.dsl1
new.instance_eval { |x| yield(x) }
end
def self.dsl2(&block)
new.instance_eval(&block)
end
def self.dsl3
new.instance_eval(&proc)
end
def self.dsl4
new.instance_eval(&Proc.new)
end
end
Foo.dsl1 { p self } => main
Foo.dsl2 { p self } => #<Foo:0x002ac2f5ec84b0>
Foo.dsl3 { p self } => #<Foo:0x002ac2f5ec8370>
Foo.dsl4 { p self } => #<Foo:0x002ac2f5ec8208>
proc に変換して block を処理すると block のスコープが Foo のインスタンスになるからかなぁ?