• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:Ruby Angleクラス作成方法について)

Ruby Angleクラス作成方法とは?

このQ&Aのポイント
  • Rubyにてゲームプログラミングをしている方へ、Angleクラスで数値を制限する方法を紹介します。
  • Angleクラスの作成方法は記号や配列を使用しないシンプルな方法です。
  • クラス参照で値を取得する方法も紹介しています。

質問者が選んだベストアンサー

  • ベストアンサー
  • notnot
  • ベストアンサー率47% (4900/10358)
回答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) とするべきでは?

tsanndayo
質問者

お礼

引き続き何度もご回答して頂きありがとうございます。 Kernelのメソッドを定義する方法は、正に思っていたような記述です!! 作成はそれでやってみます。 >いやだから、それはわかっていて、それを文字通りにするのは無理なので やはりクラス参照のみでは、Numericオブジェクトは取得できませんでしたか・・・。 上記の方法でやってみます。 >ということは、上記回答の前提の、「数値演算関係がすべて定義されているなら」もまだと言うことですね。 これについては、Angleクラス内の演算子関係を全て定義していることだと思っていました。 coerceメソッド、ヘルプで見ました。かなり使えるメソッドだと思います。 (ヘルプくらい、もっと前にしっかりと読みこんでおくべきでした・・・) 是非、これを使いたいと思います。 >Angle.new(30) + Angle.new(30) とするべきでは? もちろんそのつもりです。ただ、そういう使い方をする可能性も視野に入れておきたかったのです。 お蔭様で、思っていたような処理を組むことが出来そうです。 とても参考になりました。ありがとうございます。 これで、また一歩先に進めそうです。

その他の回答 (3)

  • notnot
  • ベストアンサー率47% (4900/10358)
回答No.3

>newを使わずに作成した方がAngleらしい記述だと思うのですが、 そんなことはないです。なぜそう思ったのですか?なんとなくですか? >また、参照もメソッドを呼び出さず、クラスのインスタンスを参照するやり方を教えて頂きたいのです。 数値演算関係がすべて定義されているなら、あとは to_int to_i to_f to_s inspect 等を適切に定義すれば良いです。

tsanndayo
質問者

補足

ご回答ありがとうございます。 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 で参照した値が計算の際にそのまま渡されると思っていたので、やはり思っていたようにはできませんでした・・・。 何度も補足してしまい、申し訳ありません・・・。 ご回答の程、宜しくお願い致します。

  • ki073
  • ベストアンサー率77% (491/634)
回答No.2

補足欄の意味が分かりにくいのですが、 angle = Angle[30] を使えるようにしたいのでしたら def self.[](ang) @angle=ang end で可能ですが、多分聞きたいことと違うような気がします。 p angle で角度が表示されるようにするには、 def inspect @angle.to_s end で可能なのですが、あくまでも表示だけを変更しているだけです。

tsanndayo
質問者

補足

引き続きご回答ありがとうございます。 回答内容がこちらから閲覧できなかった為、返信が遅くなってしまいました。 分かりづらい補足で申し訳ありません。 詳しい補足は、回答NO3のnotnot様の補足に書いたのでそちらの閲覧をお願いいたします。 何度も補足をしてしまい申し訳ありません。 作成方法については、Angle[30]の変わりに、良い記述方法のアドバイスが欲しいのです。 Angle{30}とか、何か記号を使った良い記述を教えて頂きたいのです。 (できれば、Numeric並に楽に作成できるのが望ましいです。) また、inspectが表示だけしか変更できないということに、先程気がつきました。 angle = Angle.new(30) angle  # 30(Numeric)のオブジェクト 表示だけでなく、上記のように見なされるように変更したいです。 そのような方法は、不可能でしょうか・・・? ご回答お願い致します。

  • ki073
  • ベストアンサー率77% (491/634)
回答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-BundledLibraries

tsanndayo
質問者

補足

お早い回答ありがとうございます。 質問が分かりづらくて申し訳ありません。 演算子定義などは、Vectorクラスを参考に作成できるのですが、 作成の際の記述方法が分からなくて困っています。 newを使わずに作成した方がAngleらしい記述だと思うのですが、 配列ではないので、Angle[30]などのように作成するのもどうかと思い、適切な作成方法を知りたいのです。 また、参照もメソッドを呼び出さず、クラスのインスタンスを参照するやり方を教えて頂きたいのです。 angle = Angle[30] p angle   # => 30 (angle.angleと二重に書かなくても参照可能) ということでお願い致します。