Rubyにてゲームプログラミングをしているのですが、
Angleとして使用する数値を (0..360) の範囲内に常に収める為、Angleクラスで管理しようと思っています。
そこで作成方法の質問なのですが、記号などによる適切な作成方法が分かりません。
適切な記述を教えて頂けたら幸いです。
angle = Angle[30] # Vectorを参考にしたのですが、配列では無い為、微妙な記述・・・
angle = Angle.new(30) # かと言って、普通に作成するのもどうかと・・・
また、attr_readerで参照するのも微妙な記述だと思います。
angle = Angle.new(30)
angle.angle # => 30
できればクラス参照で値を取得したいのですが、方法が分かりません。
angle = Angle.new(30)
angle # => 30
ご教授の程、お願い致します。
No.4ベストアンサー
- 回答日時:
No3です。
>Numeric並に手軽に呼び出せた方が良いと思ったからです。
それは無理です。せいぜい、組み込みクラスのRationalのように、
def Angle(x)
Angle.new(x)
end
と、クラス名と同名の関数(Kernelのメソッド)を定義するくらいですね。
>クラスのみ参照で、戻り値(Numeric)を取得したいです。
>angle # => 30(Numeric)のオブジェクト
いやだから、それはわかっていて、それを文字通りにするのは無理なので、それに対しての回答が、
>数値演算関係がすべて定義されているなら、あとは to_int to_i to_f to_s inspect 等を適切に定義すれば良いです。
です。
p angle で 30 を表示するためには、inspect を定義すれば良いし、puts angle なら to_s を定義すれば良いと言うことです。
ただ、
>30 + Angle.new(30)
>Numeric側の演算子定義を直すのも手なのですが、
ということは、上記回答の前提の、「数値演算関係がすべて定義されているなら」もまだと言うことですね。
30 + Angle.new(30) の結果は、Angleオブジェクトじゃ無くてNumericオブジェクトということでいいですか?であれば、Numericクラスを修正するので無くAngle#coerceを定義してください。
class Angle
def coerce(other)
[other, @angle]
end
end
ただ、そもそも 30 + Angle.new(30) などという計算をするのはおかしくないですか?
Angle.new(30) + Angle.new(30) とするべきでは?
引き続き何度もご回答して頂きありがとうございます。
Kernelのメソッドを定義する方法は、正に思っていたような記述です!!
作成はそれでやってみます。
>いやだから、それはわかっていて、それを文字通りにするのは無理なので
やはりクラス参照のみでは、Numericオブジェクトは取得できませんでしたか・・・。
上記の方法でやってみます。
>ということは、上記回答の前提の、「数値演算関係がすべて定義されているなら」もまだと言うことですね。
これについては、Angleクラス内の演算子関係を全て定義していることだと思っていました。
coerceメソッド、ヘルプで見ました。かなり使えるメソッドだと思います。
(ヘルプくらい、もっと前にしっかりと読みこんでおくべきでした・・・)
是非、これを使いたいと思います。
>Angle.new(30) + Angle.new(30) とするべきでは?
もちろんそのつもりです。ただ、そういう使い方をする可能性も視野に入れておきたかったのです。
お蔭様で、思っていたような処理を組むことが出来そうです。
とても参考になりました。ありがとうございます。
これで、また一歩先に進めそうです。
No.3
- 回答日時:
>newを使わずに作成した方がAngleらしい記述だと思うのですが、
そんなことはないです。なぜそう思ったのですか?なんとなくですか?
>また、参照もメソッドを呼び出さず、クラスのインスタンスを参照するやり方を教えて頂きたいのです。
数値演算関係がすべて定義されているなら、あとは to_int to_i to_f to_s inspect 等を適切に定義すれば良いです。
この回答への補足
ご回答ありがとうございます。
newが、Angleらしくない記述だと思った訳は、Angleは頻繁に使う物であり、
Numeric並に手軽に呼び出せた方が良いと思ったからです。
また、Vector[]は配列らしさを取り込んだ上手い記述だと思ったので、そのような分かり易い記述にしようと思いました。
それと、お聞きしたいことが上手く伝わらなかったようなので、質問をもう少し補足したいと思います。
またまた分かりづらい質問になってしまい申し訳ありません。
class Angle
attr_reader :angle
def initialize(angle)
@angle = angle
end
end
angle = Angle.new(30)
angle.angle # => 30(Numeric)のオブジェクト
上記のように定義するとそうなるのですが、下記のようにしたいのです。
クラスのみ参照で、戻り値(Numeric)を取得したいです。
angle # => 30(Numeric)のオブジェクト
しかし、やり方が分かりません。
google先生や、リファレンスもある程度見たのですが、見つかりませんでした・・・。
試行錯誤としては、下記のようにメソッドを組んでみたのですが、当然呼び出せません。
def self
@angle
end
このやり方で呼び出したい理由としては、下記のような計算があった時に、Numericとして渡したいからです。
30 + Angle.new(30)
Numeric側の演算子定義を直すのも手なのですが、AngleはNumeric以外の様々な場所で使われているので、
そのまま使えるのが効率的だと思っています。
演算子を直すことになると、Numeric以下の様々なクラスを修正する必要も出てきます・・・。
例としては、下記のようなケースも考えられます。
angle = Angle.new(30)
sprite = Sprite.new
sprite.angle = angle.angle # 現状、このように呼び出すしかない。
# sprite.angle = angle # 本当はこのように呼び出したい。
尚、Spriteクラスはブラックボックス化されており、ソースを弄る事ができません・・・。
(つまり、angleに渡す値はNumericでないといけないということです。)
angle.angleと、二重にangleを記述しないと呼び出せないのでは、優れた記述とは言えないと思います。
to_int、to_i、to_f、to_sは、今のところ使うつもりはないので定義していません。
inspectについてなのですが、思っていたことに非常に近いことが出来ました。ご教授ありがとうございます。
しかし、p で参照した値が計算の際にそのまま渡されると思っていたので、やはり思っていたようにはできませんでした・・・。
何度も補足してしまい、申し訳ありません・・・。
ご回答の程、宜しくお願い致します。
No.2
- 回答日時:
補足欄の意味が分かりにくいのですが、
angle = Angle[30]
を使えるようにしたいのでしたら
def self.[](ang)
@angle=ang
end
で可能ですが、多分聞きたいことと違うような気がします。
p angle
で角度が表示されるようにするには、
def inspect
@angle.to_s
end
で可能なのですが、あくまでも表示だけを変更しているだけです。
この回答への補足
引き続きご回答ありがとうございます。
回答内容がこちらから閲覧できなかった為、返信が遅くなってしまいました。
分かりづらい補足で申し訳ありません。
詳しい補足は、回答NO3のnotnot様の補足に書いたのでそちらの閲覧をお願いいたします。
何度も補足をしてしまい申し訳ありません。
作成方法については、Angle[30]の変わりに、良い記述方法のアドバイスが欲しいのです。
Angle{30}とか、何か記号を使った良い記述を教えて頂きたいのです。
(できれば、Numeric並に楽に作成できるのが望ましいです。)
また、inspectが表示だけしか変更できないということに、先程気がつきました。
angle = Angle.new(30)
angle # 30(Numeric)のオブジェクト
表示だけでなく、上記のように見なされるように変更したいです。
そのような方法は、不可能でしょうか・・・?
ご回答お願い致します。
No.1
- 回答日時:
こんな感じでしょうか
class Angle
attr_accessor :angle
def initialize(ang)
@angle=ang
end
def to_s()
@angle.to_s
end
def +(other)
self.class.new(case other
when Angle then @angle+other.angle
else @angle+other
end)
end
end
p ang1=Angle.new(30)
p ang1.angle
ang1.angle=45
p ang1
puts ang1 #=>45
p ang1+12
puts ang1+12 #=>57
puts ang1+Angle.new(12) #=>57
ang1はNumeric classではありませんので、演算は定義してやる必要があります。
演算した結果がNumericで良いのなら、forwardableを使って委譲する手もあります。
参考
http://jp.rubyist.net/magazine/?0012-BundledLibr …
この回答への補足
お早い回答ありがとうございます。
質問が分かりづらくて申し訳ありません。
演算子定義などは、Vectorクラスを参考に作成できるのですが、
作成の際の記述方法が分からなくて困っています。
newを使わずに作成した方がAngleらしい記述だと思うのですが、
配列ではないので、Angle[30]などのように作成するのもどうかと思い、適切な作成方法を知りたいのです。
また、参照もメソッドを呼び出さず、クラスのインスタンスを参照するやり方を教えて頂きたいのです。
angle = Angle[30]
p angle # => 30 (angle.angleと二重に書かなくても参照可能)
ということでお願い致します。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・人生のプチ美学を教えてください!!
- ・10秒目をつむったら…
- ・あなたの習慣について教えてください!!
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・【大喜利】【投稿~9/18】 おとぎ話『桃太郎』の知られざるエピソード
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
ビーリアルのユーザー名を変え...
-
(再質問)エクセルのマクロボ...
-
C言語の入力した文字を反転させ...
-
再起動後必ず2つのエラーが出...
-
電子書籍作成、epubファイルの...
-
Beautiful Soupのインストール...
-
秀丸エディタで、同じ記号で囲...
-
pandasでsqlite3にテーブル作成...
-
pythonエラー
-
A4 持ち込み
-
前回の質問の続き
-
あせんうぶり言語
-
これらは書誌情報だと思うので...
-
情報の表現。()内がどうしても...
-
pythonのerrorコード
-
三項でたとえば交換って
-
WinSCPで画像のように puttyを...
-
パソコンのスクリーンセーバー...
-
こういう問題分をよんだとき
-
バーチャルボックスが使えなく...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
What class are you in? には何...
-
クラス名やモジュール名の競合...
-
HSTLやSSTL等のI/Oピン
-
テンプレートの特殊化でコンパ...
-
class roomとclassroom どちら...
-
下線部の答え教えてください こ...
-
railsのform_forの使い方
-
redirect先でredirect元の変数...
-
Ruby ハッシュ継承クラス、作成...
-
Webプログラマーの方にお聞きし...
-
プログラミングRubyについての...
-
Ruby シルバーの過去問
-
変数の隠蔽とは?
-
構造体を使ったプログラム
-
No route matches [GET] "/post...
-
pythonのerrorコード
-
railsのlink_toに動的なclass指定
-
Rails AR 深い階層のテーブル参照
-
Rubyについて質問です
-
インスタンス内から自分のクラ...
おすすめ情報