こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

【Ruby】 文法的に何が悪いのかわからない

以下に示す(例1)を実行すると、
hoge
defaultString
と出力されます。

(例1)------------------------------------------------------
def hoge(str)
b=(str||'defaultString') + "\n"
STDOUT.write b
end
hoge("hoge") #hoge
hoge(nil) #defaultString
------------------------------------------------------------

下記に示す例2は、例1の2行目と3行目を1行にまとめたものです。
例1と同じ実行結果を期待しています。

(例2) ----------------------------------------------------
def hoge(str)
STDOUT.write (str||'defaultString') + "\n"
end
hoge("hoge")
hoge(nil)
------------------------------------------------------------

しかし、例2を実行すると、以下の様なエラーが出ました。
------------------------------------------------------------
hogewrite.rb:2:in `+': String can't be coerced into Fixnum (TypeError)
from write.rb:2:in `hoge'
from write.rb:4
------------------------------------------------------------
文法的に、何に違反してるのか、わかりません。

ご指導のほど、宜しくお願いいたします。

投稿日時 - 2009-12-18 18:49:35

QNo.5531850

暇なときに回答ください

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

多くの言語では、メソッド呼び出しや関数呼び出しの時に、メソッド名・関数名の後に引数を囲むカッコが必要です。
例: print(1+2)

Rubyでは多くの場合、カッコを省略できます。
例: print 1+2

さて、カッコにはこの他に、演算の順序を変えるためのカッコがあります。例:(1+2)/3

メソッド名の後にカッコがある場合、演算の順序を変えるためのカッコなのか、メソッド引数をくくるカッコなのか???
Rubyは、引数をくくるカッコとみなして解釈しようとします。そうじゃなくて演算の順序を変えるカッコのときは、引数をくくるカッコは省略できません。
例:誤: print(1+2)/3 #=> エラー
→ こう見なされている: (print(1+2)) / 3 #=> printの返す結果を3で割ろうとして、割れないのでエラー ***1
例:正: print((1+2)/3)

>文法的に、何に違反してるのか、わかりません。

文法と言うより実行時のエラーです。writeは出力した文字数を返すので str が "hoge" の場合、STDOUT.write(str||'defaultString') は 4 を返します。次に、4 + "\n" を実行しようとして、「文字列と整数は足せない」というエラーになっている。エラーメッセージの corce というのはここでは「(計算できるように値を)変換する」という意味です。

さて、上の ***1 では、わざとエラーになる例にしましたが、
例:STDOUT.write(1+2)/3
はエラーになりません。どうなるかわかりますか?


なお、改行付きで出力したい場合は、puts を使うと便利です。
def hoge(str)
puts str||'defaultString'
end

投稿日時 - 2009-12-18 20:28:51

お礼

notnotさん、ご回答ありがとうございます。
とても解りやすい説明でした。

>例:STDOUT.write(1+2)/3
>はエラーになりません。どうなるかわかりますか?

()の中の1+2の演算結果が出力されて、writeの戻り値である『1』が3で割られたって事ですね。

以下を実行して検証しました。
ret=STDOUT.write(1+2)/3.0 #=>3
puts
puts ret #=> 0.333333333333333

投稿日時 - 2009-12-19 00:18:40

ANo.2

このQ&Aは役に立ちましたか?

10人が「このQ&Aが役に立った」と投票しています

回答(2)

ANo.1

例2
2行目
STDOUT.write (str||'defaultString') + "\n"

write 先が(str||'defaultString')までで終わっていて、
+がなんだかわかんないよ。と言われているので、

STDOUT.write (str||'defaultString'+ "\n")

bに代入したものと直で構文化したものは違うので
注意が必要。

投稿日時 - 2009-12-18 19:27:17

お礼

tommy1977さん、ご回答ありがとうございました。

投稿日時 - 2009-12-19 00:01:15

あなたにオススメの質問