web-dev-qa-db-ja.com

Rubyのクラスエイリアス

私は新しいRailsアプリを同様の既存のアプリに基づいて開発しています。古いアプリには、新しいアプリのチケットに非常に似たCouponクラスがあります。すべてのコードを再利用したいクーポンで、ただし新しいクラス名。

Railsではリファクタリングが面倒なので、Ruby(属性とメソッドのエイリアスと同様))でクラスのエイリアスを作成する方法があるかどうか疑問に思います。

43
AdamNYC

Rubyでは、クラスに名前はありません。これらは、他のオブジェクトと同様に、変数に割り当てられたオブジェクトです。別の変数を介してクラスを参照する場合は、別の変数に割り当てます。

Foo = String
88
Jörg W Mittag

ファイルcoupon.rb内:

class Coupon 
  #...
end

# add this line of code to make alias for class names
# option1. if you haven't defined a "Ticket" class: 
Ticket = Coupon   

# option2. if Ticket has been defined, you have to redefine it: 
Object.send :remove_const, "Ticket"
const_set "Ticket", Coupon

「クラスとモジュールの名前を含め、大文字で始まるすべての参照は定数です」-<<メタプログラミングRuby >>、38ページ、定数セクション

16

ここに来て、a Railsモデルクラスに新しい名前を付けるためのエイリアスを作成する方法を探しています。

私は単にFoo = Barを実行できましたが、未初期化定数エラーが発生しないように、独自のモデルファイル内にFooを配置する必要がありました。例えば.

# models/foo.rb
Foo = Bar

また、has_manyhas_oneなどの関連付けでエイリアスを使用しようとする奇妙なことに気付くかもしれません。通常、ルートネームスペース(またはモデルに応じて適切なネームスペース)を使用することでそれらを回避できることがわかりましたRailsが正しい定数をオートロードしようとしていることを確認するために、構造化されています:

has_many :foo, class_name: '::Foo'
5
Mark G.

私は多かれ少なかれウォーホッグに同意します-しかし、私はあなたのクーポンクラスからチケットをサブクラス化します-そのため、データを変更する必要がある場合は、チケットクラスにコードを入れることができます

2
chrispanda

クラスが状態の変更(追加された関数、変更された定数、クラス変数など)を受けた場合、クラスの状態whenエイリアスがインスタンス化されたため、これには注意する必要がありますクラスの更新された変更を反映しません。

読みやすさを犠牲にすることなく手根管を回避するために、実際のクラスではなくエイリアスオブジェクトにラムダを格納できます。もちろん、ラムダにはクラスが含まれていますが、これにより、エイリアスがクラスのlatestバージョンを呼び出すことが保証されます。

これをsupermanpatches.rbに入れますRails初期化子(config/initializers/内)‡

LAP = lambda { LosAngelesParcel }

これでLAP[]を使用してこれを呼び出すことができ、新しく作成されたバージョンのクラスが読み込まれます。 (たとえば、l = LAP[].newによってインスタンスを作成できるようにします)

は、Railsが読み込まれ、アプリ全体に広がるときに1回実行されます。グローバル変数のような任意の場所で呼び出すことができますが、「読み取り専用」なので、話す

2
boulder_ruby