• ベストアンサー

消えたコロン

消えたコロン 以下のプログラムを実行すると、「ruby」と出力されます。なぜ「:」が表示されないのか、納得できません。どなたか、理由を解説できる方はいらっしゃいませんでしょうか?なるべく簡単な言葉でお願いします。 def func(x) puts(x[:name]) end func(:date =>Time.now, :name => :ruby, :version => 1.9)

  • ghfjri
  • お礼率92% (372/403)
  • Ruby
  • 回答数4
  • ありがとう数17

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

  • ベストアンサー
  • notnot
  • ベストアンサー率47% (4848/10262)
回答No.4

どうしてもわからなければ、「文字列とシンボルは兄弟」と思ってください。 プログラム中に文字列を書くときは、" " や ' ' などで囲みます。 プログラム中にシンボルを書くときは : を前置します(:" " や :' ' で囲んでも良い)。 "abc" == %+abc+ #⇒ 真(同じ文字列の別の書き方。入門書の「%記法」参照) :abc == :"abc" #⇒ 真(同じシンボルの別の書き方) ★文字列に対してシンボルの長所 代入や等値比較が速い ★文字列に対してシンボルの短所 大小比較が出来ない。正規表現とマッチできない。分解・連結・部分取り出し・書き換えなど加工・編集など一切が出来ない。多分まだまだある。 そういえば、以前もシンボルの説明をしました。 http://okwave.jp/qa/q5800523.html ここに書きましたが、ハッシュのキーでは、文字列よりシンボルが好んで使われます。長所が生きて、短所が関係ないので。 なお、to_s と to_sym で相互変換できます。 "abc" == :abc #⇒ 偽 (文字列とシンボルは等しくない) "abc" == :abc.to_s #⇒ 真 (変換して文字列同士の比較で等しい) "abc".to_sym == :abc #⇒ 真 (変換してシンボル同士の比較で等しい) putsに対しても相当の誤解があるようですが、どこから説明したものか。 「メソッドとは何か」をまず勉強するのかな。「たのしいRuby」等の定評のある入門書を虚心に読む。

ghfjri
質問者

お礼

ありがとうございました。 やっぱり私の知識がぜんぜん足りないみたいですね。 実はここで私が使っている本について数回質問したことがあるのですが、 みなさん微妙な反応でした。 やっぱり「たのしいRuby」を買おうと思い、先ほどアマゾンで注文しました。 結構経済的に厳しいですが、がんばってRubyを覚えたいと思います。

その他の回答 (3)

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

>この式は演算子(:name)のハッシュ値として演算子(:ruby)を設定してい 「演算子」という言葉も間違ってますね。 それはさておき、 puts :name で、:name でなく name が表示されるのが不思議ということですが、 puts "name" で、"name" でなく name が表示されるのは不思議ですか?不思議じゃないですか?

ghfjri
質問者

お礼

回答ありがとうございます。 演算子間違ってますね。確認しました。 puts "name" で、"name" でなく name が表示されるのは不思議ではありません。puts("")は""の中を返すメソッドだからです。 しかし、puts :nameは見たことがないのでわかりません。putsといえば、("")がついているものか、(変数名)がついているものしか本に出てなかったので・・・。ネットで明日(今日?)もう一度調べます。

ghfjri
質問者

補足

やはりputs :nameみたいな使い方が解説されているとこは見つかりません・・・。 シンボルの癖にシンボル扱いされてないのはなぜなんでしょうか?

  • notnot
  • ベストアンサー率47% (4848/10262)
回答No.2

:ruby というのは ruby という文字列表現を持つシンボル(Symbolクラスのオブジェクト)です。 同様に、 :+ というのは + という文字列表現を持つシンボル。 :" " というのは、空白1文字の文字列表現を持つシンボル。 シンボルという物が何かを理解されてないのでは?と思います。シンボルを簡単に説明するのは難しいですね。「構文解析時に1ワードにしてしまった文字列」でわかりますか? 例えば、aに文字列が代入されているとして、a == "abcdef" という文字列同士の比較だと、C言語レベルでは、strcmpという関数で文字列を一文字ずつ順に比較することになります。 今度は a にシンボルが代入されているとして、a == :abcdef だと、C言語レベルでは整数同士の比較1回で比較が完了します。従って文字列より処理が早いので、加工不要な文字列、例えばメソッドのパラメータなどでよく使われます。

ghfjri
質問者

お礼

回答ありがとうございます。 いちおう入門書でシンボルのところは読んだのですが、確かに理解していないかもしれません。 この式はその入門書のハッシュのところの練習問題です。 この式は演算子(:name)のハッシュ値として演算子(:ruby)を設定していて、演算子:rubyを設定してないのに、コロンなしのrubyが返ってくるのが不思議だと思っています。 やはりシンボルが理解できていないのでしょうか? RubyしかやったことないのでC言語での説明はちょっとわかりません。

  • koko_u_u
  • ベストアンサー率18% (216/1139)
回答No.1

puts :ruby とはすなわち puts :ruby.to_s だからです。 いやなら p :ruby でどうぞ

ghfjri
質問者

お礼

回答ありがとうございます。 puts :rubyがすなわちputs :ruby.to_sである。 puts :ruby.to_sは、:rubyを文字列で返すということですよね? なぜコロンが消えるのでしょうか? もう少し説明してくださるとうれしいのですが・・・。

関連するQ&A

  • Rubyの引数が理解できません。(初心者です)

    プログラミング言語を覚えたいと考え、諸々の事情からRubyを独学したいとおもっております。 先日、「14歳からはじめるRuby…」という本を購入し、早速勉強を始めたのですが、引数でいきなり躓いてしまいました。 以下のような例文がありましたが、原理(理屈?)が理解できません。ご教唆お願いします。 001 def syomei s 002  puts "" 003  puts "============" 004  puts "" + s 005  puts "============" 006 end 007 puts "What's your name?" 008 name = gets.chomp 009 puts "Hello," + name + "!" 010 syomei name なぜ、これでメソッドの中へ変数が引き渡されるのかが理解できません。 「008 name」で初めて出てくるnameと引数"s"が何故イコールになるのでしょうか? 例えば(全くのデタラメですが)、「010 syomei name.s」であったり「010 syomei name = s」などのように定義付けされているのであれば、納得できるのですが…。 初歩中の初歩なのはわかっているのですが、理屈を理解したいと思ってます。よろしくお願いします。

  • Module#method_addedの挙動

    すいません、Rubyのドキュメントを見ながら動作を追っていて、疑問に感じたので質問をさせてください。 Module#method_addedというメソッドが追加されたタイミングで動作するメソッドがあります。 定義場所がModuleクラスの中なので、Moduleにメソッドを追加したら、それがmethod_addedを呼び出すと思って試して見たのですが、何故かそうなりません。 何故なのか理由がわからないんですが、教えていただけないでしょうか? ------------------------------------------------------------------ class Object def self.method_added(*_) p self.class.name p __method__ p _ end def self.singleton_method_added(*_) p self.class.name p __method__ p _ end end class Module def self.method_added(*_) p self.class.name p __method__ p _ end def self.slngleton_method_added(*_) p self.class.name p __method__ p _ end end module Foo def self.foo end def foo2 end end class Bar def self.bar end def bar2 end end ------------------------------------------------------------------ 出力結果 ------------------------------------------------------------------ "Class" :singleton_method_added [:bar] "Class" :method_added [:bar2] ------------------------------------------------------------------ 動作環境は、Mac rubyのバージョンは2.4.0です。 ruby 2.4.0p0 (2016-12-24 revision 57164) [x86_64-darwin16]

    • ベストアンサー
    • Ruby
  • 【ruby】【文法】スパークラスのスーパークラスのメソッドを呼び出したい

    スパークラスのスーパークラスのメソッドを呼び出したいです。 たとえば、Hoge3のスーパークラスがHoge2で、さらにそのスーパークラス がHogeの時、Hoge3からHogeのメソッドを呼び出したいのです。 もう少し具体的に説明させてもらいます。 class Hoge  def initialize()   @name='hoge'  end end class Hoge2 < Hoge  def initialize()   super   @name='hogehoge'  end end class Hoge3 < Hoge2  def initialize()   super #これではスーパークラスHoge2のメソッドが呼ばれてしまう。   puts @name  end Hoge3.new() 上記実行結果は、hogehogeが出力ですが、 スーパークラスのスーパークラスが設定した@name値、 'hoge'が出力されるようにしたいです。 『Hoge3クラスはHoge2クラスを継承すればよいではないか?』 とも思うでしょうが、Hoge2クラスには、Hogeには無い機能が多く拡張されてると考えてください。 ご指導のほど、宜しくお願いいたします。

  • 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で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】特異クラスを使って,File.statをカスタムしたい

    File.statに、nameというメソッドを追加したいです。 st=File.stat('hoge.txt') puts st.name #=> hoge.txt 上記のように使いたいのです。 そこで、以下の様に書いてみました。(行頭のスペースは全角です) class File  class << self   def stat(file)    st=File::Stat.new(file)    class << st     def name      @file     end    end    st   end end end st=File.stat('./hoge.txt') puts st.name #=> nil 上記実行結果はnilが出力され、期待した結果は得られませんでした。 上記の様に書いた理由を以下に記します。 クラスメソッドstatは、file.rbのclass Fileの中に定義されていて、 stat.rbのFile::Stat.new(file)を戻り値としていました。 stat.rbのclass File::Statのinitializeでは、 def initialize(file)  @file = file  (略) end となっていたので、上記の様に書いてみたのですが、何が悪いのでしょうか? ご指導のほど、宜しくお願いいたします。

    • ベストアンサー
    • Ruby
  • インスタンス内から自分のクラス名を取得する方法

    クラスインスタンス内から自分のクラス名を取得しようと思うと、self.class.nameで取得できますが、type.nameでも取得できます。 しかし、typeは非推奨メソッドとなっているため、警告が出て、このままでは使用することができません。 素直にself.classを使えばいいのかもしれませんが、selfのワンクッションがどうにも気に入りません。 スマートな記述方法あったら教えて下さい。 # self.class.nameを使用する場合 class MyClass  def print_classname   puts self.class.name   # puts class.name これはエラー  end end # type.nameを使用する場合 class MyClass2  def print_classname   puts type.name # これはdeprecatedの記述で警告が出る  end end

  • 【ruby】【文法?】ブロックをbreakした時。。

    質問を見ていただいて有難うございます。 質問を一言で言うと、 「メソッドの中で呼び出し元がbreakを使った事を検知できるか?」 となるのでしょうか。。。以下に詳しく質問を記述いたします。 引数に配列を渡すと、その配列をブロックに一つずつ返してくれる メソッドhoge()があるとします。 以下の様に使います。 ------------------------------------- hoge([0,1,2]) do |x|  puts x end 実行結果 0 1 2 ------------------------------------- このhoge()は、実行中にエラーが発生した場合、トラップして falseを返す事とします。(何事もなければtrueを返します。) このhoge()を以下の様に書きました。 def hoge(arg)  begin   arg.each do |x|    yield x   end  rescue   false  else   true  end end 以下の様に使います。 ------------------------------------- ret=hoge([0,1,2]) do |x|  puts x end puts ret ? 'success' : 'fail' 実行結果 0 1 2 success ------------------------------------- ------------------------------------- ret=hoge(nil) do |x|  puts x end puts ret ? 'success' : 'fail' 実行結果 fail ------------------------------------- ここまでは、よかったのですが、hoge()のブロックの中で、breakを使うと hoge()の戻り値はnilになってしまいます。 ------------------------------------- ret=hoge([0,1,2]) do |x|  break if x==1  puts x end puts ret puts ret ? 'success' : 'fail' 実行結果 0 nil fail ------------------------------------- ここで質問です。 最後の例は、hoge()として異常系ではないので、retにtrueを与えたいのですが、どうしたらよいでしょうか? ご指導のほど、宜しくお願いいたします。

    • ベストアンサー
    • Ruby
  • rubyのプログラム

    プログラミング初心者です。参考書のソースコードをそのままコピペして実行したのですが、エラーが出てしまいます。どこが間違っているのかご指摘いただけると助かります。 ソースコード #encoding: cp932 # うるう年かどうかによって時間数は変わります puts 24*365 puts " (#{24*366}になる場合もある) " 実行結果 >ruby calc.rb calc.rb:4: invalid multibyte char (Windows-31J) calc.rb:4: syntax error, unexpected tIDENTIFIER, expecting $end puts "(#{24*366}になる場合もある)" ^ >Exit code: 1 パソコンOS Windows7 rubyのバージョン 1.92

    • ベストアンサー
    • Ruby
  • rubyの構文(&&を用いた条件分岐について)

    ruby初心者です。 最近、ruby on railsで書かれたソースを引き継ぎ解析を行っています。 その中で、以下のような構文が出てきました。 ========================================= num = 0 bool = false vals = '' puts 'start' num == 0 && bool && if vals  puts 'true' else  puts 'false' end puts 'end' ========================================= 上記プログラムを実行すると、if ~ end までが実行されませんでした。 そこで、変数boolをtrueに変更して再実行したところ、if文が実行されました。 そこで私は、上記プログラムは以下と同値であると解釈しました。 ====================================== (省略) if num == 0 && bool  if vals   puts 'true'  else   puts 'false'  end end ======================================= 以上を踏まえて・・・ 1.私の解釈は正しいでしょうか? 2.間違っている場合、正しい処理の解釈を教えていただけますでしょうか?または参考URLを教えていただけますと助かります。 文の最後に"&&"がついている文を見たことがなく、ネットで調べても 正解らしいものが掲載されていなかったので質問させていただきました。 拙い説明で申し訳ありませんが、よろしくお願いいたします。

    • ベストアンサー
    • Ruby

専門家に質問してみよう