実現したいこと
戻り値とputsの違いがわからず苦戦しています。
色々な質問や記事を自分なりに解読し以下にまとめてみたので、
違っている点があれば教えていただけると幸いです。
発生している問題・分からないこと
■putsとreturnの違い
-putsとは-
puts は学習や確認のために使うもので、実際にウェブ上に表示させるために使用するものではなく、 contoroller内(●●.rb)に学習や確認のために一時的に使用するもの。
-returnとは-
returnは実際にウェブ上に表示させるためのコードで、
returnを記述しないとputsと同じで処理結果をウェブ上に表示できない
該当のソースコード
Ruby
1class Menu 2 attr_accessor :name 3 attr_accessor :price 4 5 def info 6 return "#{self.name} #{self.price}円" 7 end 8 9 def get_total_price(count) 10 total_price = self.price * count 11 if count >= 3 12 total_price -= 100 13 end 14 return total_price 15 end 16end 17 18menu1 = Menu.new 19menu1.name = "ピザ" 20menu1.price = 800 21 22puts menu1.get_total_price(3)
試したこと・調べたこと
- teratailやGoogle等で検索した
- ソースコードを自分なりに変更した
- 知人に聞いた
- その他
上記の詳細・結果
class Menu
attr_accessor :name
attr_accessor :price
def info
"#{self.name} #{self.price}円"
end
def get_total_price(count)
total_price = self.price * count
if count >= 3
total_price -= 100
end
return total_price
end
end
menu1 = Menu.new
menu1.name = "ピザ"
menu1.price = 800
puts menu1.get_total_price(3)
補足
return を使用しても使用しなくても
コンソール結果は同じ結果になりました。
(現在ウェブ上で確認できる環境が整っていないため、progate という学習アプリでコンソール結果のみは確認できました。)
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2024/10/08 06:29
2024/10/08 07:04
2024/10/08 08:51 編集
2024/10/08 08:58
回答5件
0
こんにちは。
はっきりと言ってしまうと、現在の質問者さんの解釈は本質を捉えられていないため、ほぼ誤りです。
(例えると、交通信号機のことを「赤くなったら立ち止まるという遊びのこと」と理解していたとしたら、言いたいことは分かるが全く理解していないと思われるでしょう)
プログラミングについてどこまで知識を持っているのかが分からないため説明が難しいですが、
基礎的な考えの部分から説明してみます。
簡単のため、あえて厳密ではない表現を使いますがご容赦ください。
まず、ruby にはメソッド (関数) というものがあることは知っていますでしょうか。
これはプログラムのロジック中に書かれるもので、「叩く (呼び出す) と、中でごちゃごちゃ動いたあと、戻り値と呼ばれる何かを吐き出すおもちゃ」のようなものです。
ruby に存在するあらゆるメソッドは、叩くと戻り値を返します。
質問者さんのコードにある get_total_price
メソッド:
ruby
1 def get_total_price(count) 2 total_price = self.price * count 3 if count >= 3 4 total_price -= 100 5 end 6 return total_price 7 end
は、count
を渡して叩くことで total_price
が計算されて出てくるというメソッドです。
他に例として、「自販機でジュースを買うメソッド」を考えてみると、お金とジュースの種類を渡して叩くと中でごちゃごちゃ動いたあと戻り値 (ジュース) が出てくる、といった感じです。
このように ruby の世界では、あらゆるロジックに必ず戻り値というものが存在しているわけです。
メソッドをイメージすると、何か作業をお願いできる同僚のことを想像してみてください。
同僚に仕事をお願いすると、ごちゃごちゃ働いたあと、仕事の結果を返してくれることになると思います。
すなわち、同僚 (メソッド) に仕事をお願いする (呼び出す) と、何か仕事をして、仕事の結果 (戻り値) が返ってくるという感じになるわけです。
このように、戻り値は全てのメソッドに存在しているわけですが、
メソッドを呼び出したあと、その結果を使わない (必要ない) 場合があると思います。
同僚に「アレやっといて」と仕事をぶん投げて、その後どうなったかを考える必要がないタイプの仕事があることを思い出してください。
メソッドは「必ず戻り値を返さないといけない」ので、そういうときは「なんの意味もない空の値」を返しておけば良いわけです。
ruby ではこのような場合では nil
という値を利用します。
呼び出すだけで役目を果たすタイプのメソッドは基本的に nil
を戻り値にしています (しておけばいい)。
さて、puts
ですが、これは出力したいデータを受け取って、戻り値は nil
を返すただのメソッドです。
つまり、アレやっといてと言えば勝手に仕事をしてくれるタイプの同僚の一人というわけですね。
同僚だと考えた場合、これは「出力させたいデータ (書類) を渡したら、(プログラマに) FAX してくれる」というような仕事をしてくれるものと言えます。
これを呼び出すときは、書類を渡してあとはお願い、という形になるわけです。
まとめて整理すると、
- 全てのメソッドは必ず戻り値を返す (逆に言うと、戻り値を返さないメソッドは存在しない)
- ただし、(呼び出し元が) 戻り値を使う必要がないメソッドもある
puts
はただのメソッドの一つで、外の世界 (プログラマ) にデータを表示させるだけの仕事をするもの- 「FAX しといて」が自分の仕事とあまり関係ないように、
puts
を呼び出しても自分の仕事内容には影響しない (だからnil
を返している)
というわけで、
戻り値と puts
は概念から全く別物なので、比較すること自体が不可能なものなのです。
プログラムはメソッドの組み合わせで動く (パラメータを渡し、戻り値を受け取る) ため、戻り値こそがプログラミングの基本であり、
puts
は「データをプログラマに見せる」ためのただのメソッドであるから、これを呼び出すことはロジックには関係がないということが分かると思います。
(もちろん、「puts
でいい感じの文字列を出力する」ことがプログラムの主目的となる場合もあるわけですが、それについては本回答では触れていません)
一通り質問の主題について回答したつもりですが、分からない点がある場合はこの回答のコメントでお知らせください。
投稿2024/10/08 08:11
編集2024/10/08 08:23総合スコア4228
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2024/10/08 08:37
2024/10/08 08:39
2024/10/08 08:40
2024/10/08 09:02
2024/10/08 09:25
2024/10/08 09:57
0
色々な質問や記事を自分なりに解読し以下にまとめてみたので、……
putsとreturnの違い
以下は公式のドキュメントからの引用です。これらの説明を読んでみても basashitosushi さんの疑問が解消されるとは到底思えませんが、参考までに上げておきます。
puts
メソッド
puts(*objects) → nil
Equivalent to
$stdout.puts(objects)
puts(*objects) → nil
Writes the given objects to the stream, which must be open for writing; returns nil.
return
キーワード
By default, a method returns the last expression that was evaluated in the body of the method. In the example above, the last (and only) expression evaluated was the simple sum 1 + 1. The return keyword can be used to make it explicit that a method returns a value.
return
Exits a method. See methods. If met in top-level scope, immediately stops interpretation of the current file.
公式ドキュメント内では keyword
の定義を見つけることができませんでしたので、おそらくプログラミング言語における一般的な意味(意義)として使用されていると思われます。以下、Wikipedia からの引用です。
The terms "reserved word" and "keyword" are often used interchangeably - one may say that a reserved word is "reserved for use as a keyword" - and formal use varies from language to language.
In a computer language, a reserved word (also known as a reserved identifier) is a word that cannot be used as an identifier, such as the name of a variable, function, or label - it is "reserved from use". This is a syntactic definition, and a reserved word may have no user-defined meaning.
Stack Overflowでも似た様な質問が散見されます。
- Using "puts" vs "return" in Ruby method
- What's the difference between `puts` and `return` result?
- return vs puts
以下はYouTubeにある解説動画です。
投稿2024/10/09 01:34
総合スコア20574
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
コメントに書く量じゃなさそうなのでここに書きます。 回答ではありません。すみません。
コメントにあるように、
独自でprogateも4回復習し、その後多額のお金を払いプログラミングスクールに通う
というような経験をされた方が
戻り値とputsの違いについて
という ような内容の質問を複数し、それらでたくさんのやりとりをしたうえで、
puts は学習や確認のために使うもので、実際にウェブ上に表示させるために使用するものではなく、
contoroller内(●●.rb)に学習や確認のために一時的に使用するもの。
returnは実際にウェブ上に表示させるためのコードで、
returnを記述しないとputsと同じで処理結果をウェブ上に表示できない
というような、まったく的外れな結論(すみません)を出してしまうことに驚きを感じています。
「一度に理解をするのは難しいから最初は30%の理解でカリキュラムを進めていってください。復習しているうちにわかるようになってきますから」と言われてその通りにやっていたのですが、復習しているうちに、どう足掻いてもわからず、今に至ります。
別の例に言い換えるより、実際のコードで説明していただける方が分かりやすいかもしれません。
このあたりの発言を見ていると、物事を抽象化して捉えて理解するのが苦手なのかもしれません。だとすると、プログラミングというスキルを見につけるのはすごく困難かもしれません。プログラミングというのは抽象的なものであり、また、抽象度に複数階層があるからです。
前の質問の回答に書きましたが、putsについて説明すれば、通常以下のようなことになります。
まずはコンピュータとプログラムについてです。
プログラムはコンピュータの中で動いており、コンピュータと外部とのやりとりは、キーボードやマウス・ディスプレイ・USB・ネットワークなどいろいろな経路を通じて行なわれます。一方、コンピュータは内部で動作するプログラムに対して入出力のための多種多様な仕組みを提供しており、標準入力と標準出力は一般的なものです。 そして、 その標準入力はキーボードに、標準出力はコンソール(ターミナル)出力に接続されていることが多いです。
rubyの標準関数であるputsは、標準出力に文字列を出力する機能を持っています。
以上がputsを理解するために必要な最低限の知識です。通常はこれをそのまま覚えて理解して利用しています。
また、説明の中に関数も戻り値もでてきません。putsが実現していることを理解するのに関係ありません。
なので、通常「戻り値とputsの違い」は何だろうとは思いません。
returnは実際にウェブ上に表示させるためのコード
何故そういう結論が出たのかわからないのですが、まずはputsに近い「ウェブ上に表示させるため」の仕組について。
さきほど、コンピュータはプログラムに対して入出力のための多種多様な仕組みを提供していると書きました。その中の標準出力はコンソール経由で文字列を送るためのものでした。 Webを含むネットワーク経由での情報送受信のための仕組みはsocket(ソケット)と呼ばれます。
標準入出力は特に何もせずに使うことができましたが、socketを使うにはいろいろ準備が必要になります。ただ、準備してしまえば、sendなどの関数を使って情報を送ることができます。また、railsなどのフレームワークを使うと、そういった面倒な設定を簡単にすることができます。
最後に「return」について。
returnは、完全にプログラムの内部の話です。コンピュータでいろいろな処理を実行するためにプログラムを書きますが、最近の言語ではプログラムを関数を使って構造的に書くのが一般的です。
プログラムを関数の組み合せで作る場合に、関数間で情報をやり取りする方法の 1つが戻り値です。
そして、rubyでは関数を終了させて戻り値を指定するためにreturnを使います。ただし、rubyは便利機能として、returnを省略できるようになっています(あちこちで説明されてますね)。
ある時、returnを書いても書かなくても結果が同じだったのは、そういう関数のプログラムの書き方をしたからであり、rubyの仕様だからです。
投稿2024/10/08 14:50
総合スコア13687
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
焦点を絞って整理しましょう
returnとは何か
ここではプログラムにおける一般的なreturn
の概念ではなく、Ruby
における戻り値の仕様について考えます
既に多くの回答にもある通り、Ruby
における戻り値は以下の仕様となっています
関数の末尾に宣言された値を戻り値とする
現在、混乱の元になっているのはreturn
の仕様だと思います
return
が何のためにあるのかを知れば、理解の助けになるでしょう
とはいえ、難しいことではありません
Rubyにおけるreturn
の用途は以下の一点に限られます
関数の途中で値を返す場合に使う
何故関数の途中で戻り値を返したいのかと言えば、何らかの理由により関数の処理を中断し、値を返したいからです
return
を使用しない場合、Rubyの仕様によって戻り値の取得はその関数が終了するまで待たなければいけません
しかしreturn
を置けばそれ以降の処理は実行されません
これにより戻り値を取得するための余分な動作や演算は必要なくなります
プログラミングでは、このような余分な処理をしばしばオーバーヘッドと呼びます
つまりオーバーヘッドの回避にreturn
による関数の強制終了が必要とされます
そのため
実際にウェブ上に表示させるためのコード
という理解は間違いとなります
return
の有用性については以下のような記事が参考になるでしょう
たまたま見つかったので貼っておきます
putsとは何か
puts
は引数に渡された値を標準出力へ流す関数です
標準出力は与えられた値を画面に表示します
一連の処理を終えるとnil
を返します
何故nilなのか
nil
とは大雑把に紹介すると値が何も無い状態を示す宣言です
関数内で戻り値としてこれが指定されたり、あるいは関数からこれが返された場合には、その関数は値を何も返さないことを示します
有り体に言えば、それらの関数は呼び出し元に無を返しています
puts
に期待される動作は値を標準出力へ表示することです
puts
から何か値が返されることを期待して使用する関数ではありません
このようなケースでは、戻り値を作るという処理は、むしろ邪魔になります
puts
を呼び出す度に何か戻り値用の値が作成されては、その分計算量が増えて動作が遅延する可能性があります
すなはちオーバーヘッドが発生した状態です
puts
には、外部から受け取った値を速やかに内部で破棄してもらった方が、プログラマとしては好都合です
なので、この関数はあえて戻り値を何も返しません
標準出力に表示される実行結果は戻り値ではありません
これはハードウェアによってモニター上に描画された文字列という名のグラフィックの生成結果に過ぎません
この種類の関数の主な用途はデバッグにあります
プログラムが上手く動かない時、変数の値の変化や異常値の特定を確認するために、変数の状態を可視化する目的での利用が主となります
puts
はあくまで関数です
対するreturn
は命令です
この違いを正しく認識することが理解への足がかりとなります
投稿2024/10/08 18:13
編集2024/10/08 18:18総合スコア60
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
理解がおかしいです。
おそらく、「プログラミングとはどういうことか」「Rubyでプログラムはどのように書くのか」などを学ばず、それらを理解できていない状態で、いきなり、それらを理解していることを前提として書かれたテキストを使ってRailsのようなフレームワークの学習から入ったので、理解が混乱しているのかと思います。
まずは、「プログラミング入門」や「Ruby入門」から入りましょう。
おそらく「プログラミング未経験者向けのRuby入門」的な書籍1冊で十分だと思います。
質問に端的に回答すると、
・puts
とは、引数を文字列化して標準出力に出力するメソッド(Kernelモジュールのputs
の場合)
・return
とは、引数の値を返り値としてメソッドを終了させる言語構文
・メソッドの返り値とは、a = メソッド呼び出し
と書いた時に、変数a
に代入される値
です。これらが100%理解できるまで入門を続けてから、Railsに取り組みましょう。
フレームワークを使ったプログラムの中でこれらが使われた時に、どういう効果を持つのかは、書かれた場所次第です。
基本の理解が出来ている状態で、フレームワークの各種クラスやメソッドを学べば、すぐに想像が付くはずです。
追記
コメントへの返信が長くなったので、回答に追記します。
独学でprogateHTML とRuby を一通りやり終え、かつプログラミングスクール(Ruby)を卒業しましたが、
なんと!
しかし、メソッドの戻り値が理解できていないということは、まだ「入門途中」の状態かと思います。
・putsとは、引数を文字列化して標準出力に出力するメソッド(Kernelモジュールのputsの場合)
これは理解しています。returnや戻り値が理解できません。
ということですが、「戻り値とputsの違いについて」という風に全く関係の無い2つの違いを問うているので、両方とも理解できていないのかと思いました。
理解できていないのは、メソッドとメソッドの返り値についてですね。
・returnとは、引数の値を返り値としてメソッドを終了させる言語構文
引数の値を返り値というのがよくわからず、なぜ引数が出てくるのかが理解できません。
引数ってカッコの中に入れる値のことですよね? 以下でいうと(shop, proce) が引数
def menu(shop,proce)
のshop
とproce
は、メソッドmenu
の引数(仮引数)です。
私が書いたのは、return の引数のことです(return total_price
と書いた時のtotal_price
のこと)。
他にも、コマンドプロンプトなどでruby aaaa.rb
というコマンドを実行したとするとaaaa.rb
がコマンドruby
の引数です。
最初の回答に書いたことと同じようなことになりますが、
「引数」という言葉は、文章の中で使われた時にどういう意味を持つのかは、書かれた場所次第です。
なぜreturnの話をしているのにメソッドが出てくるのでしょうか?
は、
returnとは、引数の値を返り値としてメソッドを終了させる言語構文
と書いた通りですが、return
はメソッドの中に書くからです(例外ありだが今は気にしない方が良い)。
というか、「メソッドとその返り値」がしっかり理解できていれば、「return
は返り値を指定する方法の1つ」と理解できるはずで、「メソッドとその返り値」がしっかり理解できていない状態で、return
の意味を理解するのは無理です。
それならreturn に書かれている以降の処理を削除すればいいだけじゃんと思いました。
Ruby
1def foo(x) 2 return x*2 3 puts x 4end
なら、puts x
は無意味なので、削除するのが正しいです。
Ruby
1def foo(x) 2 if x>0 3 return x*2 4 end 5 puts "引数が正でない" 6 -1 #正でない場合はこれが返り値 7end
のような時は、return
以降を削除できません。
メソッド・関数とその返り値
数学の関数は分かりますよね。「メソッドの返り値」は「数学の関数値」と思うと良いかもしれません。
数学の関数で、f(x) = x*2+1
だとすると、f(10)
は 21 ですが、この21が関数の値です。
中学高校レベルの数学でも、g(x) = 0 (x<0の時); x (x>=0の時)
のような場合分けの定義も出てきます。これをRubyで書くと、
Ruby
1def g(x) 2 if x<0 3 return 0 4 else 5 return x 6 end 7end
このケースだとRubyではreturn
を書かなくてもいいですが、書くか書かないかはこの場での本質ではないので書いてます。
数学から離れて、別の例を出すと、IO.write("ABC.txt","ABCDEFG")
というメソッド呼び出しを行うと、
・返り値:書き込んだバイト数の7
・副作用:カレントディレクトリのABC.txt
という名前のファイルにABCDEFG
という文字列を書き込みます
ということになります。
puts IO.write("ABC.txt","ABCDEFG")
だと7
が標準出力に表示されます。(アクセス権その他の理由でファイルに書けなかった場合を除く)
「副作用」というのは、返り値以外でのメソッドの外への何らかの影響のことです。
ファイルやストレージ関係の処理、ネットワーク通信、画面表示、グローバル変数・クラス変数・インスタンス変数の更新など。
IO.write
のように副作用を主目的として使うメソッドは多いです。質問にあるputs
もそうですね。require
もメソッドですが、そうです。
「~~~~について理解できないので教えて下さい」という情報ゼロ型の質問じゃなくて、今回のように「~~~を~~~~という風に理解してるが、合ってますか?」という形での質問は良いと思います。コメントで分からない点をさらに明確にするのも良い感じで進んでいます。
が、リアルタイムでなく、表情も分からないこう言う場でのやりとりで学ぶのには限界はありますね。まあ、もう少し先まで行けそうな気がしています。
投稿2024/10/08 07:23
編集2024/10/09 13:06総合スコア85778
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2024/10/08 07:40
2024/10/08 07:42
2024/10/08 07:46
2024/10/08 07:47
2024/10/08 07:48
2024/10/08 07:58
2024/10/08 08:02
2024/10/08 08:05
2024/10/08 08:09
2024/10/08 09:05 編集
2024/10/08 09:27
2024/10/08 09:55 編集
2024/10/08 11:07
2024/10/08 11:13
2024/10/08 11:22 編集
2024/10/08 13:33
2024/10/08 13:57
2024/10/08 14:00
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。