以下の例を参照してください。2番目の方法を使用するのが最善だと思いますが、最初の方法も機能します。どの方法が最適で、他の方法を使用した場合の結果は何ですか?
class Test
def start
p "started"
end
test = Test.new
test.start
end
class Test2
def start
p "started"
end
end
test2 = Test2.new
test2.start
以下の例を参照してください。2番目の方法を使用するのが最善だと思いますが、最初の方法も機能します。どの方法が最適で、他の方法を使用した場合の結果は何ですか?
class Test
def start
p "started"
end
test = Test.new
test.start
end
class Test2
def start
p "started"
end
end
test2 = Test2.new
test2.start
間違いなく、2 番目のバリアントの方がはるかに理にかなっていると思います。最初のものはエラーを引き起こしませんが、オブジェクトのインスタンス化は完全に時代遅れで無意味です。外部変数は、クラスのスコープ内では表示されません。
var = "string"
class A
var = A.new
end
puts var #=> string
クロージャーはありません。外側var
はクラス内とは異なります。これは、作成後にオブジェクトが「失われ」、アクセスできなくなり、最終的に GC の対象になることを意味します。
最初の例が「機能する」と言うとき、このコンテキストで機能するということは、クラス スコープでオブジェクトを作成した直後に、新しく作成されたオブジェクトのメソッドを呼び出すことができることを意味します。ただし、後で使用するためにそのオブジェクトを参照として保持することはできません (クラス (インスタンス) 変数に割り当てずに)。
後で使用するための参照が必要なく、そのような「ワンショット」操作を本当に実行したい場合は、オブジェクトをインスタンス化せずに呼び出すことができるクラス メソッドを使用するかinitialize
、.インスタンス化のたびに実行する必要がある場合。
ロード時にそれ自体のオブジェクトを作成するクラスを定義することはお勧めできません。オブジェクトはそれ自体でのみ使用でき、親のスコープでは使用できません (もちろん、 を介してアクセスすることもできますObjectSpace::each_object
)。
あなたはこれをいくつもの方法で行うことができます。それはあなた次第です。ここに楽しいものがあります...
class Test
def start
p "started"
end
new
end.start
もっと深刻なことに、最初の例はすべてを 1 つのクラスにカプセル化しています。スクリプトの場合は問題ありません。すべてを独自の名前空間に配置し、ほとんどの場合、不可解なメイン オブジェクト コンテキストを回避します。必要に応じて、ネストされたクラスを定義できます。
ただし、2 番目のアプローチはより一般的です。
SOLID
できるだけクラスを作るようにしてください。to_s
ドメイン オブジェクトを表すクラスには、常に適切なメソッドを提供してください。attr
。代わりにattr_reader
andを使用してください。attr_accessor
Struct.new
自明なアクセサー、コンストラクター、および比較演算子を定義する の使用を検討してください。Struct.new
。それを拡張すると、不要なクラス レベルが導入され、ファイルが複数回必要な場合は奇妙なエラーが発生する可能性もあります。(@@)
継承における「厄介な」動作のため、クラス変数の使用は避けてください。public
、protected
、およびprivate
メソッドを、それらが適用されるメソッド定義と同じくらいインデントします。その下のすべてのメソッドに適用されることを強調するために、可視性修飾子の上に 1 行、下に 1 行の空白行を残します。これは、Ruby のベスト プラクティスに関する最良のドキュメントです: https://github.com/bbatsov/ruby-style-guide