「なぜこれをやりたいのですか?」という質問はしないでください。私は特定の目標を念頭に置いて、Ruby の隅々まで探索しているだけです。
一部の Ruby クラスは、 #new メソッドを明示的に呼び出すのではなく、かっこだけでインスタンス化できます。例えば、
irb> require 'pathname'
irb> p=Pathname('/etc/xdg/autostart')
=> #<Pathname:/etc/xdg/autostart>
irb> n=Pathname.new('/etc/xdg/autostart')
=> #<Pathname:/etc/xdg/autostart>
irb> p==n
=> true
また、Integer(4.5) のように、これをキャスト/強制に使用するものもあります。そして、おそらく私がまだ出会っていない、または思い出せない他の用途があるでしょう。
ただし、カスタム クラスでこれを行う方法は見つかりませんでした。
irb> class Foo ; def initialize(*args) ; @args=args ; end ; end
=> :initialize
irb> f1=Foo.new(1,2,3)
=> #<Foo:0x00007f330a29f4e8 @args=[1, 2, 3]>
irb> fp=Foo(1,2,3)
(irb):7:in `<main>': undefined method `Foo' for main:Object (NoMethodError)
Did you mean? for
私が理解できる唯一のことは、Pathname と Integer (たとえば) の両方が C コードを使用しており、どういうわけかカーネル メソッドになってしまうということです。
irb> Object.method(:Pathname)
=> #<Method: #<Class:Object>(Kernel)#Pathname(_)>
irb> Object.method(:Integer)
=> #<Method: #<Class:Object>(Kernel)#Integer(*)>
irb> Object.method(:Foo)
(irb):10:in `method': undefined method `Foo' for class `#<Class:Object>' (NameError)
Did you mean? for
したがって、これは C/.so 拡張コードによって提供されるもののようです。
しかし、次のような手間をかけずにネイティブ Ruby コードで簡単に実行できるでしょうか?
irb> Object.define_method(:Foo) { |*args| Foo.new(*args) }
=> :Foo
irb> Foo(1,2,3)
=> #<Foo:0x00007f330a3b9018 @args=[1, 2, 3]>
これらのグローバル メソッドは、カーネルで定義されたいわゆるモジュール関数です。次の方法で独自のグローバル関数を定義できます: (メソッドの定義に Ruby 3 の短縮構文を使用)
module Kernel
def Foo(...) = Foo.new(...)
module_function :Foo
end
上記は、すべての引数を Foo.new に転送するメソッド Kernel#Foo を定義しています。オブジェクトにはカーネルが含まれているため、次の方法でオブジェクト内から Foo インスタンスを作成できます。
Foo(1, 2, 3) #=> #<Foo:0x000000010633e120 @args=[1, 2, 3]>
さらに、 module_function により、メソッドがクラス メソッドとして利用可能になります。
Kernel.Foo(1, 2, 3) #=> #<Foo:0x0000000108b00398 @args=[1, 2, 3]>
また、インスタンス メソッドをプライベートとしてマークするため、他の明示的なレシーバーで呼び出すことはできません。
:hello.Foo(1, 2, 3)
# NoMethodError: private method `Foo' called for an instance of Symbol
これは、Integer、Pathname なども統合される方法です。
クラスに対応する組み込みグローバル メソッドは、主に値をそのクラスに変換することを目的としていることに注意してください。 Integer(“123”) #=> 123。引数を渡すだけではありません。 (整数はnewにも反応しません)