• ベストアンサー

Ruby 同じ名前のメソッド

始めましてよろしくお願いします。 さっそくなんですが Rubyで class A def dash( a, b ) end def dash( a ) end end というような使い方をしたいのですが どのように書けばいいのでしょうか? ちなみにこの書き方だと、後に書いた dash( a ) の方だけが有効になりました。

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

  • ベストアンサー
  • you-m
  • ベストアンサー率58% (190/327)
回答No.4

一応情報を追加しておくと、公式仕様にはありませんが、オーバーロードを実現するライブラリを書いた人はいます。 個人サイトのようなので、ちょっとURLは掲載できませんが、「ruby オーバーロード ライブラリ」等で検索すると、見つかると思います。 まあ、使うかどうかは微妙なところかと思いますが、参考までに。

maruchan0488
質問者

お礼

回答有難うございます。 さすがRubyですね そんなライブラリを作っている人がいるとは。。。 さっそく探してみます。

その他の回答 (6)

  • you-m
  • ベストアンサー率58% (190/327)
回答No.7

余談になりますが・・・ 型の有無にこだわっていると、本質を見失います。 おそらく、型指向の言語での構造化プログラミングに慣れているかただと思いますが、もう少しオブジェクト指向自体について勉強された方がいいと思います。 目先の方法論よりも、プログラム自体の設計についての考え方を根本から変えることで、同じ結果を導き出すまったく別のプログラムが書けることに気が付くと思います。 例題だけだと、用途がよくわかりませんが、たとえばこの場合だと、dashメソッド以外共通の要素をもったクラスXを 継承して、AとA´を定義し、後はファクトリーメソッドのデザインパターンに当てはめる方が、よりオブジェクト指向チックに解決できるような気がします。 というより、そのようなコードにしないと本当にRubyの良いところが見えてきません。 参考までに。

maruchan0488
質問者

お礼

アドバイスありがとうございます。 非常に核心を突いた言葉で米神が痛いです。。。 買ってそのままになっているデザインパターンの本を 読み直してみようと思います。

  • Bo_Bo
  • ベストアンサー率65% (97/149)
回答No.6

#5 です。 肝心な引数を渡すのを忘れていました。 訂正したものを投稿します。 #!ruby -Ks class TEST private  def method0()   puts "引数なし用のメソッド呼び出し"  end  def method1( arg )   puts "引数1個: '#{arg}'"  end  def method2( arg1, arg2 )   puts "引数2個: '#{arg1}', '#{arg2}'"  end public  def pubMethod( *arg )   case arg.size   when 0    method0()   when 1    method1( arg[0] )   when 2    method2( arg[0], arg[1] )   else    puts "例外処理する?"   end  end # end def end # end class obj = TEST.new obj.pubMethod() obj.pubMethod("foo") obj.pubMethod("foo", 10) obj.pubMethod("foo", 10, "bar")

maruchan0488
質問者

お礼

回答ありがとうございます。 サンプルコードまで書いて頂いて 恐縮です。。。 引数の個数だけで呼び出しを判断するんだったら このやり方で充分だと思うので 今回は、Bo_Boさんのやり方でやろうと思います。 余談 Ruby系の言語をやる前は、型を意識しないで プログラムが書けるのか~ っと感心していましたが いざブログラムを書いてみると 型がないことによる 不便さだけが目立ちますorz もう少し触れていけば考えが変わる事を願います。

  • Bo_Bo
  • ベストアンサー率65% (97/149)
回答No.5

> 知りたい事は、同じメソッド名を定義して > 引数の数でどちらかのメソッドを読んでくれるか という事です。 の発言に反応します。 下記の動作イメージはどうですか? ●引数の個数判定で分岐して、対応するプライベート・メソッドを呼ぶ 【注意】  インデントのために全角の空白を使用!  実作業へは、半角空白2個に置き換えてください。 ---- 以下ソース ---- #!ruby class TEST private  def method0()   puts "引数なし用のメソッド呼び出し"  end  def method1()   puts "引数1個用のメソッド呼び出し"  end  def method2()   puts "引数2個用のメソッド呼び出し"  end public  def pubMethod( *arg )   case arg.size   when 0    method0()   when 1    method1()   when 2    method2()   else    puts "例外処理する?"   end  end # end def end # end class obj = TEST.new obj.pubMethod() obj.pubMethod("foo") obj.pubMethod("foo", 10) obj.pubMethod("foo", 10, "bar")

  • you-m
  • ベストアンサー率58% (190/327)
回答No.3

単純に書かれた要件だけを満たすのであれば、bを省略可能な引数として、内部で2種類の処理を分岐によって書くのがひとつの方法です。 しかし、オブジェクト指向っぽくないので、スマートではないですね。 しかし、参考URLを見てもらうとわかると思うのですが、言語仕様的に一般的に言うオーバーロードができません。 Rubyの作者の発言なので、間違いないでしょう。 やり方によっては、逃げ道は無いわけじゃないというところですね。

参考URL:
http://www.ruby-talk.org/cgi-bin/scat.rb/ruby/ruby-list/1401
maruchan0488
質問者

お礼

回答ありがとうございます。 まさに知りたい事はその事でした。 同時に普通のやり方では、実現できない事もわかりました。 う~ん ちょっと残念・・・

  • JeanneNet
  • ベストアンサー率48% (100/208)
回答No.2

あ、間違えた... orz

maruchan0488
質問者

補足

すいません 私の説明が足りませんでした。 知りたい事は、同じメソッド名を定義して 引数の数でどちらかのメソッドを読んでくれるか という事です。 型がある言語の場合、引数の数が一緒でも型が違うと 違うメソッドとして認識してくれますよね? Rubyでは、型がないので せめて引数の数で メソッド呼び出しを分けてくれないかな っと思って質問しました。

  • JeanneNet
  • ベストアンサー率48% (100/208)
回答No.1

関連するQ&A

  • Rubyのsuperclassメソッドについて

    Rubyについての質問です。処理系は1.8.7です。 class Foo def initialize(a) @a = a end end のようなクラスを作成し、そのインスタンスを foo = Foo.new(1) のように作成します。 このとき、 foo.superclassを呼び出すと NoMethodError: undefined method `ancestors' for #<Foo:0x2b691220cc88 @a=1> とエラーになります。 一方で class FooExt < Foo def initialize (a,b) @b = b super a end end のようにFooを継承したクラスを作り、 fooext = FooExt.new(1,2) fooext.superclass とすると => Foo とsuperclassメソッドが動作します。 このsuperclassメソッドはどこで追加されたものなのでしょうか?

  • rubyでメソッド内で引数名、値を取得

    Rubyでメソッドの引数名をメソッド内部で取得するような事は可能でしょうか? def hoge(a,b,c) # ここでa,b,cの引数名、またその値を取得 # 例えば、{:a=>1, :b=>2, :c=>3}のようにHashの形式で得るなど。 end local_variablesだと、引数も含まれますがその他で定義したものも拾ってしまうため、他の方法を探しています。 わかる方がいれば教えていただけますでしょうか。

  • ruby undefined method

    class Hoge def body "aaa" end end def up(arg) arg.upcase end res=Hoge.new res.body = up(res.body) puts res.body 上記を実行すると、undefined method `body=' for #<Hoge:0x2b36454> (NoMethodError) になります。 最後の2行を以下のように変えるとうまく動作します。 tmp=res.body tmp = up(tmp) puts tmp この理由が理解できません。 説明して頂けませんか?

  • Ruby

    class CDPlayer def playDisk(disk) puts "playing a "+disk+".\n"; end end class CDRadioCaset < CDPlayer def playRadio(channel) puts "playing a"+channel+"\n"; end def playCaset(tape) puts "playing a "+tape+"\n"; end end class DVDRPlayer < CDPlayer def playDisk(disk) puts "playing a"+disk+"\n" end def recoredDisk(disk) puts "recording to a "+ disk+". \n" end end cd=CDPlayer.new puts "CDPlayer. \n" cd.playDisk("CD") radio=CDRadioCaset.new puts "\n CDRadioCaset. \n" radio.playRadio("Radio") radio.playCaset("Caset") dvd=DVDRPlayer.new puts "\n DVDRPlayer.\n" dvd.playDisk(" CD or DVD") dvd.recoredDisk("disk") の意味わかる方、教えてください

  • Ruby

    #!/usr/local/bin/ruby class Foo def []=(x,y) print "Hello,",x,y,"!\n" end end bar = Foo.new bar["wor"] = "ld" 上記実行結果は Hello world! になるのですが、これが理解できません。 上手く説明してくれませんか?

  • rubyでScalaのようにコールバックを変数として定義するには?

    rubyでScalaのようにコールバックを変数として定義するには? 最近Scalaの勉強を始めました。自分の一番好きな言語はrubyなので、比較しながら勉強してます。 参考書によると、関数をオブジェクトとして扱えるのがScalaの特徴との説明がありました。例えば、以下のような例なのですが、(行頭スペースは全角) class Kuku(a:Int,b:Int){  def calc(func:(Int,Int)=>String):String={   return func(a,b)+a*b  } } val f1=(a:Int,b:Int)=>a+"*"+b+"=" println(new Kuku(3,5).calc(f1)) これをrubyで書くと、(行頭スペースは全角) class Kuku  def initialize(x,y)   @x=x   @y=y  end  def calc   yield(@x,@y)+(@x*@y).to_s  end end puts Kuku.new(3,5).calc{|a,b| a.to_s+'*'+b.to_s+'='} とまでは書けたのですが、コールバック(ブロックパラメータの部分)、上記例だと |a,b| a.to_s+'*'+b.to_s+'=' の部分 を変数として定義(Scalaの例のf1として定義するところ)する方法を知りません。 このように関数を変数として定義する事ってrubyではできないと考えるのですが、そういった認識で間違いないでしょうか? ご指導の程、よろしくお願いいたします。

    • ベストアンサー
    • Ruby
  • Rubyについて質問です

    Rubyについて質問です class Document #省略 def each_word word_array = words index = 0 while index < words.size yield(word_array[index]) index += 1 end end end d = Document.new('Truth', 'Gump', 'Life is like a box of...') d.each_word { |word| puts word } このような例題があるのですが、 このまま実行しても引数エラーがでてしまいます。 「省略」のところをどのように追加すれば実行できるようになりますか? 参考書:ELOQUENT RUBYの中の例題です ちなみに実行結果は以下の通りです Life is like a box of ... どうかよろしくお願いいたします

  • Ruby の 文法に困ってます。

    以下のようなソースの場合、to_sメソッドは何時呼ばれているのでしょうか。またどういう意味を成しているのでしょうか。 Ruby初心者のためご教授頂けないでしょうか。 よろしくお願いします。 class Vector   attr_accessor :x, :y   def initialize(x=0, y=0)     @x = x     @y = y   end   def length     Math::sqrt(@x ** 2 + @y ** 2)   end   def to_s      "(#{@x},#{@y})"   end   def <=> other     length <=> other.length   end end arr =[] arr << Vector.new(2,2) arr << Vector.new(3,2) arr << Vector.new arr.sort.each do |item|   puts item end 結果は以下になります。 (0,0) (2,2) (3,2)

    • ベストアンサー
    • Ruby
  • 呼ばれているメソッドがおかしくなります

    rubyのコードを書いていた時の疑問です。 以下のコードを見てみると、呼ばれているメソッドがおかしくなっているところがあるように見えます。 a = "hoge" module Mage def to_s :fuga end end a.extend(Mage) a.to_s # => :fuga a.singleton_class.ancestors # => [#<Class:#<String:0x007fdeea15c4a0>>, Mage, String, Comparable, Object, Kernel, BasicObject] 上のコードはObext#extendでto_sメソッドの挙動を上書きされていますが 継承をたどっていくと、Stringクラスのto_sメソッドではなくMageモジュールのto_sメソッドの方が、深いところに挿入されています。 継承関係と、実際に呼ばれるメソッドに齟齬があるように見えるのですが、これはどういう原因で起こるのでしょうか?

    • ベストアンサー
    • Ruby
  • メソッド定義の際の引数で

    楽しいRuby第4版のp.120で def a(a, b: 0, c:0)  [a, b, c] end のように、必須の引数とキーワード引数を混在 させることができると説明があったので試しに def meth(a, b: 2, c: 3, *args)  [a, b, c, args] end p meth(1,2,3) のように、必須の引数とキーワード引数と不定の 引数を混在させたところエラーが返りました。 やはり、不定の引数*argsまで混在させられないの でしょうか? irbで試すとメソッド定義をendで括った瞬間に エラーが返りましたんで、きっとこれが原因だと 思うのですが。

    • ベストアンサー
    • Ruby