質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.39%
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Q&A

6回答

1417閲覧

戻り値や戻り値として返すの意味がよくわかりません

basashitosushi

総合スコア0

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

0グッド

1クリップ

投稿2024/09/15 20:13

実現したいこと

戻り値や戻り値として返すの意味がわからないため理解したい。

発生している問題・分からないこと

①戻り値とはなんのどこにある値がどこに戻るのでしょうか?

②ソースコードの return total_price はなんのためのコードでしょうか。
また、total_priceはどこに戻るのでしょうか。
total_price の結果はtotal_price -= 100で出てるのになぜ
return total_priceが必要なのでしょうか

③return total_priceがあってもなくても同じ結果になるのは何故でしょうか

該当のソースコード

class Menu attr_accessor :name attr_accessor :price def info return "#{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)

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

以下見ましたがわからずでした
https://terakoya.sejuku.net/question/detail/22397

補足

特になし

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

dodox86

2024/09/15 23:56

Ruby, Ruby on Railsに限りませんが、teratailでも過去、戻り値/返り値に関して同じような質問が何度もされています。"初心の方あるある"なのかもしれませんね。 [戻り値や返り値について] https://teratail.com/questions/43067 「キーワードで検索」欄で「戻り値」で検索して過去の質問回答を覗いてみることもお勧めします。
TakaiY

2024/09/16 01:32

すでに付いている回答にもありますが、これって、rubyのメソッドは「returnが呼び出されなかった場合は、 body の最後の式の値を返す」という仕様が混乱を招いていると思います。 これが理解できれば解決するのでは?
basashitosushi

2024/09/16 07:42

戻り値というのは出力結果と同じ意味ですよね? puts とreturn の違いがまずわからないです涙 「returnが呼び出されなかった場合は、 body の最後の式の値を返す」ですが returnが呼び出されなかった場合という意味がまずわからないです、、、、 returnを呼び出すがわからないです、、 どこに呼び出すのかそもそも元のポジションがどこにあるのかがよくわからないです。 なんのためにreturnがあるのかもわからないです。 returnの話でなぜbody が出てくるのかもわからないです涙涙涙涙涙涙涙涙 どの記事見てもわからないです。
dodox86

2024/09/16 08:03 編集

もしかして質問者さんは記事だけ読んで、プログラムを実際には動かしていない状態でしょうか? そうであればご自身で実際にコードを書いて実際に動かして失敗なり成功なり体感すると理解が違うと思うのですが。コードである式や文が実行されてはじめてデータが入出力されるというイメージが付いていないのではないかな、と。
basashitosushi

2024/09/16 08:23

実際にコードを打ち込んでいます。結果が同じになるので何がなんだかわかりません。
basashitosushi

2024/09/16 08:24

できればごちゃごちゃしたくないので、質問に対しての回答以外はお控えいただけますと幸いです。
dodox86

2024/09/16 08:25

> できればごちゃごちゃしたくないので、質問に対しての回答以外はお控えいただけますと幸いです。 承知しました。失礼いたしました。
txty

2024/10/09 04:28 編集

Rubyでは、全てのメソッドは必ず戻り値を返す (逆に言うと、戻り値を返さないメソッドは存在しない)ということが他のページに書かれていました。間違えてすいません。。どういう場合か知りたかったので、copilotにまかせました def example_method(arg1, arg2) end a = example_method(5, 3) # 出力: nil def example_method(arg1, arg2) return nil end a = example_method(5, 3) # 出力: nil def example_method(arg1, arg2) return end a = example_method(5, 3) # 出力: nil まだあるかも… cでRubyについては、知りませんが、関数中に return が途中にあるときはそれ以上関数をすすめたくないときとかですよね。話は変りますがint Function(a,b){ return5; }を使うと、if (Function(2,5)==5)などになるんじゃなかった?。もしここで、return文 をつかわないとint Function(2,5) int a=2, int b=5などは関数中で寿命がなくなってしまいますよね。ポインタを引数に 使えば大丈夫ですが。Rubyでは、全てのメソッドは必ず戻り値を返す (逆に言うと、戻り値を返さないメソッドは存在しない)ということが他のページに書かれていた。 Rubyここがわかりやすかったです。https://pikawaka.com/ruby/return-value returnを省略したらどうなるかとかがcと違います。 #メソッド定義 def calc_double(num) p '倍返しだ' num * 2 #最後に記述される式の値が返り値になる end #呼び出し元 calc_double(4) "倍返しだ" => 8 とか。他にも。 で、提示されていた参考文献では三角形の面積が一番簡単だと思った。 //三角形の面積を計算する関数 function triangle(x,y){ //演算結果を返却する return x*y/2 } let triangle_area=triangle(10,20)  triangle(10,20)は返り値で100で、triangle_areaは100になるから。思いつきletはひとつでも、ふたつでも同じ気がしましました。copilotだとletの使われかたは主に、ーと違うことが出てくる気がしたので。 以下バッシュ a=1+5 echo $a 1+5と表示 let a=1+5 echo $a 6と表示されます と書いたんですがbashではこうなるのですがRubyでは違うことを調べてみてわかりました。まったくわからないことしかわからなかったのですいません。
basashitosushi

2024/10/08 09:33

ありがとうございます!!! すみません、一度に理解するとパンクしそうなのでまず以下から質問させてください。 >Rubyでは、全てのメソッドは必ず戻り値を返す (逆に言うと、戻り値を返さないメソッドは存在しない)とい>うことが他のページに書かれていました。間違えてすいません。値かえさないときはreturn nilだそうです。 全てのメソッドは必ず戻り値を返す それ以外はreturnかnilとのことですが、 returnは戻り値を返すメソッドで nilも結局nilという戻り値を返しているように見えて 結局どれも戻り値に見えてしまいます。
txty

2024/10/08 10:43 編集

引用 はい、Rubyの nil は他のプログラミング言語でいう null に相当します。nil は「何もない」状態を表す特別なオブジェクトで、変数が値を持たないことを示します。 nil 値がなにもないということじゃない。#define NULL 0という構文がcにもあるし。(いちおうcopilotで調べてから喋ってる)別のこといってたらすいません。NULLは、ポインタ使ってないからどうかという気もするが.
guest

回答6

0

関数内の変数は、その関数の処理が終了すると消滅します
特に数値のような不変値をクラスなどを介さずに直接代入した場合、変数が消滅するとそれを外部から参照する手段もなくなります

そのため関数の外に持ち出したい値は、何らかの手段で外部にそれを複製する仕組みを必要とします
そのための機能が戻り値であり、それを実行するための命令として、returnは存在します

メモリ内には、戻り値を一時的に記憶しておくための領域が確保されています
retutnで返されたtotal_priceの値はいったんこの領域に保存された後、呼び出し元へ再度それをコピーします
この時点でtotal_priceそのものは消滅していますが、値はコピーされたものなので生存します

より正確には値そのものはメモリ内のどこかに常に存在し、total_price及びその戻り値はその値に対する参照情報を管理していますが、いずれにせよ関数の外に持ち出せない情報の一つなので、このような仕組みが必要となります

もしtotal_pricereturnしない場合、値(結果)は変数と共に関数内で消えます
そうなると例え最終的にtotal_priceの持つ値(結果)は同じでも、それを確認、参照する術は失われます

戻り値はこう言った理由で必要とされます

尚、言語によっては関数の終了時に宣言される値を戻り値として認識する仕組みを採用するケースもあります
このような言語では戻り値をreturnでマークする必要はありません

コメントへの補足

「関数内の変数は、その関数の処理が終了すると消滅します」という部分ですが、消滅してしまったら、puts で処理も結果が出せないのでは?と思ってしまいます

まず、関数の実行には優先度があります

puts menu1.get_total_price(3)

上記の式であればmenu1.get_total_price(3)->putsの順序で呼び出されます

これは、putsを実行するために、まず引数を受け取る必要があるためです
ここでは引数に与える値の生成をmenu1.get_total_price(3)が担当します

本回答の中で、以下のような説明を行いました

メモリ内には、戻り値を一時的に記憶しておくための領域が確保されています

関数はこの領域に戻り値を一時的にコピーしておくことで、本来は関数内で消えてしまう値を保存しています

putsは引数でこの領域から値を受け取ります
つまりmenu1.get_total_price(3)から地続きに値が渡されるのではなく、いったんこの関数が外部へ出力した値を引数へ代入した上でputsを実行します

そのため戻り値となる値がmenu1.get_total_price(3)の内部で消失していようが関係ありません
putsが利用する値は、その消失の寸前に外部の領域へコピーされた値だからです

数値のような不変値をクラスなどを介さず」のこともクラスを介さずが何でクラス話が出てくるのかも理解ができません

これはクラスから生成されるインスタンスへの参照を介して、関数の内外で値を共有する手段が言語仕様としてサポートされているためです

これを適切に運用するには参照型アドレスの概念を抑えている必要がありますが、概要だけを掻い摘むと、インスタンス内にフィールド値として値を定義しておくことで、その値はインスタンスを保持する変数からアクセスできるようになります

この時、インスタンスの性質が「可変」なのか「不変」であるのかで値に対する操作の可否が変わります
コメントの内容を鑑みる限り、このトピックについてはおそらくまだ未履修だと思われるので、現段階では話半分に流し読みして頂いて構いません

本題

詰まる所、putsreturnの持つ意味は同一ではありません
putsは引数に渡された値を標準出力へ表示する関数の一種です
「標準出力へ表示する」とは、putsの内側で標準出力を呼び出す関数を宣言し、そこに引数の値を委譲することであると考えて下さい

言語の外には、コンソールやターミナルといった大元の実行環境があります
これらは様々な言語が連携することでシステムの構築と制御を行っています
プログラムというのは、この巨大な制御系の一部を間借りして稼働するプロセスに過ぎません

つまりputs内で値が消えようが、その値が言語の外部、すなはち実行環境の制御系に渡されていれば、あとの処理はその制御系の管轄であって、putsではないのです

putsはその内外を繋ぐ一種の窓口として存在します
putsの役目は標準出力という外部の処理系へ値を投げることであり、いったん役目を果たしてしまえばプログラムそのものを終了させようが問題はありません
最もプログラムを終了させた時点で言語と連携していた処理系と共にプロセスは終了するので、全ての値は破棄されます

returnの機能はあくまで呼び出し元に値を吐き出すことであり、この手続きは言語内で完結しています
一方putsの機能は外部の実行環境と連携することであり、その一連の処理は言語内で完結しません
そのためputsの終了を以ても「標準出力へコピーするために用いられたputs内の値」が消えるだけで、複製後の値は消失しません

最も言語の外へ渡された値を言語内に引き戻すことはできないので、言語内からは実質完全消失したも同然となります

投稿2024/09/15 23:22

編集2024/10/08 15:10
Manabu

総合スコア44

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

basashitosushi

2024/10/08 04:44

返信が遅くなってしまい申し訳ございません! まだ理解ができていない状態で、 「関数内の変数は、その関数の処理が終了すると消滅します」という部分ですが、消滅してしまったら、puts で処理も結果が出せないのでは?と思ってしまいます。 puts でdef 内でプログラミングされた処理結果がputs に返されてるので戻り値もputsも同じように見えます。
basashitosushi

2024/10/08 04:51

うう、、涙涙涙涙涙涙涙涙涙 最初から最後の分まで理解ができず苦しんでいます。 プログラミングは向いてないのでしょうか。。 「数値のような不変値をクラスなどを介さず」のこともクラスを介さずが何でクラス話が出てくるのかも理解ができません。
maisumakun

2024/10/08 05:01

> 消滅してしまったら、puts で処理も結果が出せないのでは?と思ってしまいます。 はい、そのとおりです。putsで画面に出力してしまった場合、(標準出力自体に仕掛けを行うような荒業を行うなら別ですが)「プログラム内から」putsした値を利用する方法はありません。
basashitosushi

2024/10/08 06:40

ご回答ありがとうございます!!!putsもreturn も結果的に同じということなんですかね? ちょっと自分にはレベルが高くて理解しきれなかったので、自分でもわかるような記事を探して、まとめてみました。簡単にいうとこのような感じでしょうか? ■putsとreturnの違い -putsとは- puts は学習や確認のために使うもので、実際にウェブ上に表示させるために使用するものではなく、 contoroller内(●●.rb)に学習や確認のために一時的に使用するもの。  -returnとは- returnは実際にウェブ上に表示させるためのコードで、 returnを記述しないとputsと同じで処理結果をウェブ上に表示できない
maisumakun

2024/10/08 06:47

いくつも質問が分散すると、どこで何をやり取りしたのかが混乱してしまいます。どこか1箇所で行いましょう。
guest

0

戻り値というのは出力結果と同じ意味ですよね?
puts とreturn の違いがまずわからないです涙

なるほど、そこでしたか。
すぐにわかるとは思いませんが、理解の助けになれば。


戻り値と出力結果は全く別の物で考えかたです。環境によっては戻り値が出力結果になる場合もありますが、それは、そうなっているからであって、別の概念です。
(以降、関数とメソッドを同じものとして扱います。 通常メソッドは関数の一種です)

・ 出力結果
プログラムはコンピュータで動作します。そのコンピュータにはキーボードやマウスなどの入力装置や、モニタやスピーカなどの出力装置が付いています。それらはコンピュータと外部の世界とをつなぐためにあり、プログラムが何か有用なことをするためには入力装置や出力装置を使って外部とやりとりする必要があります。
putsなどの出力のための仕組み(これも関数/メソッドですが)は、何かを出力装置に出すためのものです。

・返り値
返り値は、上記のようなプログラムの外のことではなく、プログラム内部の話です。
プログラムはいろいろな要素を組み合わせて作られています。その要素の一つが関数です。関数は特定の処理を実施するように作られていて、関数を呼び出すことでその作られた処理を実行することができます。

ここで、2つの数を足す関数add(a, b)を例として考えます。この関数は2つの引数aとbを足す機能を持っていますが、その足した結果をどうすればいいでしょうか? プログラムの中で add(2, 5)とすれば7が得られるはずですが、それを出力すればいいのかというと、先に書いたように出力というのはプログラムの外の世界への出すことです。内部に残っていなければ、以降の処理で使うことができないので、それでは困ります。何らかの方法で内部に結果を残す方法が必要になります。
関数から計算結果など何かを受け取る方法はいろいろありますが、その1つが、返り値を使うことです。

ruby

1sum = add(2, 5)

と記述し、add関数が結果を返す関数であれば、受け取った結果がsumに入り、結果をsum変数で受け取ることができ、以降の処理で利用することができます。

「returnが呼び出されなかった場合は、 body の最後の式の値を返す」ですが
returnが呼び出されなかった場合という意味がまずわからないです、、、、
returnを呼び出すがわからないです、、
どこに呼び出すのかそもそも元のポジションがどこにあるのかがよくわからないです。
なんのためにreturnがあるのかもわからないです。

さきほどのaddをrubyで書いてみましゅ。

ruby

1def add(a, b) 2 s = a + b 3 return s 4end

この関数は呼ばれると、aとbの値を変数sに保存し、それをreturnしています。 なので、この関数の返り値は引数を足した値になります。 そして、この 足し算の行と returnの行な2行がこの関数のボディーです。
さで「returnが呼ばれなかった場合」とはどういうことかというと、この関数ではそのようなことは起きません。同じ関数を以下のように書いくと「returnが呼ばれない」関数になります。

ruby

1def add(a, b) 2 a + b 3end

これは、どこにもreturnが無いので、関数を読んでも「returnは呼ばれない」ということになります。この関数を読んで、返り値を得ようとしたら、どのようなことが起きるでしょう。
このような場合、rubyでは、「body の最後の式の値を返す」という言語仕様になっています。このとき、bodyは「a + b」のみです。 a + b の式の値は、2つを足したものになっていますから、結果として足したものが返ります。
なぜ「body の最後の式の値を返す」というような仕様になっているかというと、大抵の処理では、返す値を最後に計算するので、であれば、returnを省略することができれば便利だと作者が考えたからです。
多くの言語はそのようになっておらず、たとえばpythonではreturnの無い関数は何も返さず、返り値をうけとろうとすると「その関数は何も返さないよエラー」が発生します。

どこに呼び出すのかそもそも元のポジションがどこにあるのかがよくわからないです。

returnを「呼び出す」というのは、そこに書くという意味で、どこか別のところにいるものを呼んでくるをいうことではありません。プログラミングの言い回しの一つです。英語でも「call(呼ぶ)」という単語を使います。というか、元が英語で呼ぶは訳語ですねたぶん。


質問を受けて追記

コードが記述されているのに、残すのがよくわからず

プログラムが実行ざれるとき、書いてあるソースコード上にある変数や関数を実際になぞるように動作していると考えているのかもしれませんが、そうではありません。そこにある変数や関数は定義であり、実際にプログラムそのものを使って計算が行なわれているわけではありません。

プログラムが実際に実行されるとき、プログラムのプロセルの中で作業用の領域が作られ、その領域に変数などが作られて、それを定義どおりに操作することで処理が進みます。

ruby

1x = 200 2y = 100 3 4puts(x) 5puts(y)

これが処理されるとき、

  • 作業領域が作られます。
  • 作業領域に変数xが作られ、そこに200が 代入されます。
  • 作業領域に変数yが作られ、そこに100が代入されます。
  • putsメソッドに、作業領域にあるxの値である200が渡され、呼び出されます。(200が表示される)
  • putsメソッドに、作業領域にあるyの値である100が渡され、呼び出されます。(100が表示される)

というようなことが起きます。

さて、関数が呼ばれるとき、その作業領域は一時的に別の場所にしまわれて、その関数用の別の作業領域が作られます。 そして、その関数の処理が終了して元の処理に戻るとき、作られた作業領域は破棄されてしまいます。

先程の処理で関数addを呼んでみましょう。

ruby

1x = 200 2y = 100 3z = add(x, y) 4 5puts(x) 6puts(y) 7puts(z) 8 9# 以下はエラー 10puts(a) 11puts(b) 12puts(s)

add関数は、returnのある版だとしましょう。
add(x, y)が 呼ばれると

  • 現在の作業領域が一時的保存場所にしまわれます。
  • 新たな作業領域が作られます。
  • add関数の定義にある変数はa と bが作られ、引数200と100が代入されます。
  • 定義の通り足し合され、変数sに代入されます。
  • 最後に s に入っている値が返されます。
  • 関数用に作られか作業領域は破棄されます。
    返り値は、システムがそのために用意した領域に格納されているのねなくなりません。
  • しまってあった呼び出し元の作業領域が取り出されて展開されます。
  • 返り値をzに代入するところから再開します。

のように進みます。そのあとは想像の通りに動作しますが、最後の3つはそんな変数は無いというエラーになります。(1つめで止まるでしょうが)。なぜなら、a, b, s の各変数は破棄された領域に作られたものなので、もう存在しないからです。

返り値は、この破棄される作業領域にある値を、呼び出し元でも使えるようにするための方法の一つということです。

投稿2024/09/16 09:29

編集2024/09/16 13:59
TakaiY

総合スコア13584

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

basashitosushi

2024/09/16 13:17

ありがとうございます!!!!!! まだまだ部分的に理解し難い概念があるようです涙 (おそらく自分はプログラミングは向いていないです。が、なんとか理解するまで頑張りたいと思っています。) 「返り値」の説明の中で質問させてください。 何らかの方法で内部に結果を残す方法が必要とのことで「return」を使用するとのことで、returnの意味がようやくわかりました。返すというより、内部で計算した値を内部に残すための値ということですね! そこで、質問なのですが、 コードが記述されているのに、残すのがよくわからずで、そもそもメソッドの中身のそれぞれの処理は残すために記述していると思っていたのですが、それをさらにreturnで残すのがよくわからずです。 add(a, b) sum = add(2, 5) 上記のように既にコードが記述されているのに return で結果を残すのはなんのために残すのかいまいちピンときません、、、
TakaiY

2024/09/16 14:00

コメントについて追記しました。
basashitosushi

2024/09/16 19:42 編集

ありがとうございます!!! >body の最後の式の値を返す」というような仕様になっているかというと、大抵の処理では、返す値を最後に計算するので、であれば、returnを省略することができれば便利だと作者が考えたからです。 上記のいただいた回答ですが、bodyの最後の式を返す仕様になっているのに、returnをわざわざ記述する意味はあるのでしょうか。 記述した方がいい時としない時の差はなんでしょうか。 というのもプログラミング教室に半年ほど通っていたのですが、その際にたくさんのコードを記述し学習したのですが、returnを使ったコードを使用したことがないのです。 計算式がある時だけ必要ということでしょうか。
TakaiY

2024/09/17 01:27 編集

> returnをわざわざ記述する意味はあるのでしょうか。 returnの必要性でしょうか。 あると便利だと言語の作者が思ったからでしょう。 最後に評価した値でないものを返したいときに必要になります。たとえば、良い例ではありませんが、税込の価格を計算してDBに登録し、税込の価格を返す関数は、最後の処理の値を返すように作るのは難しいですね。(returnを書かずに変数だけ書けばできますが、実際にはそれはreturn相当だと思います) 処理を分岐ささせて中断したいときにも使えますね。(工夫すれば無くても書けますが) ただ、言語の中にはLisp系の言語のように最後の値を返すだけでreturnに相当する機能を持たないものもありますので、絶対に必要ということでもありません。 > returnを使ったコードを使用したことがない プログラムの書き方は、言語により差はありますが、言語仕様でギチギチに決っているわけではなく、インデントの幅など見た目の問題を含めてある程度自由に決めることができます。どちらでもいいときにreturnを書く書かないについても同様です。 どのような方針で記述するのかは、個人の好みやチームの方針・会社の方針・コミュニティーの慣習などいろいろな決まりかたがあります。個人で書いているのであれば、どちらでも好きにすればいいでしょう。 僕はrubyを書かないので多くのrubyプロジェクトでどのように扱われているかわかりませんが、いろいろ見てみれば傾向は別るのではないでしょうか。
guest

0

③return total_priceがあってもなくても同じ結果になるのは何故でしょうか

条件によっては同じ結果になりませんcount >= 3が成立しない場合、メソッドの返り値はifが条件を満たさなかったことによるnilとなります。

(なお、Rubyではメソッド最終行でreturn 値ではなく、だけ書いておくことも多いです)

投稿2024/09/16 07:55

maisumakun

総合スコア145830

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

returnは関数の中で使われ、returnが呼び出されたあとの処理を無視します。つまりreturnをすると処理がそこで止まります。

returnは関数の呼び出し元に値を返すことができます。その値は任意であり、関数の定義でreturnに続く値(=式)です。

定義された関数は呼び出すことができ、呼び出した際に関数内の処理が実行され、returnされる値は呼び出し元に返されます。
関数の呼び出しは式(=値)として使えます。

なお、関数の中で入力を受け取ったり、出力をしたり、プロパティの値を変更したりする操作は副作用と呼ばれ、副作用がある関数は実質的にただの式としては表せないかもしれないです。

関数定義もreturnもただの文法でしかないのでこういう決まりだと思うしかないところです。

投稿2024/09/16 06:01

utm.

総合スコア220

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

utm.

2024/09/16 06:02

ちなみに関数にはスコープがあることがほとんどです。 スコープを狭めることは良い設計と一般に言われています。
basashitosushi

2024/09/16 07:46

①「returnは関数の中で使われ、returnが呼び出されたあとの処理を無視します。つまりreturnをすると処理がそこで止まります。」 「return が呼び出された後」というのはコードでいうとどの部分になりますか? なぜreturnが必要なのでしょうか? ②「returnをすると処理がそこで止まります。」returnするとというのは  return のコードを使うとということですかね? なんのためのreturnなのでしょうか涙
utm.

2024/09/16 12:08

1. 関数の定義ブロックの中です 2. なんのためのリターンかはプログラムにより様々でしょうから、あまり本質的な問ではないです 質問からズレますがひとつ思ったのはこういう初心者の質問をする時は、自分がどの程度知識があるのかを明らかにすると、いい回答が得られるかもしれないです。
basashitosushi

2024/09/16 13:22

他者さんの回答からreturn はメソッド内部で処理した値を残すためのメソッドというふうにやっと理解しました。 return が呼び出された後の処理というのは return を使用して、その値が残された後ということでしょうか? 呼び出すというのがいまいちピンときません、、 そんな初心者ってことですか、、、
utm.

2024/09/16 13:57

returnを一般にメソッドとは言わない気がするのですが、Rubyでは言うのですかね。。。 プログラミング(というか構造化プログラミングの文脈)では、ブロックという一つの単位があります。 例えば、ifで始まってendで終わるのが一つのブロックです。 関数にも同様に関数の定義ブロックがあります。 以下はGPTに出力してもらいました。 def check_value(value) if value > 10 return "10より大きい" elsif value == 10 return "ちょうど10" end # ifのいずれにも当てはまらなかった場合 return "10以下" end この関数では、 return "10より大きい" が実行されたとき、その下にあるコードは実行しません。 実行せずに呼び出し元に制御を戻します。 例えば、 a = 1+1としたら、aが2になるよに、 a = 関数()というように呼び出したら、aはreturnの値になります。 これはプログラムから見たときに一定の処理をまとめておいて、後から何度も呼び出したり、あるいはスコープを狭める(変数の寿命を短くする)ことで、ほかのプログラムに影響が出ないようにするなど、の意図があります。 関数定義をしなくてもプログラムはかけます。 関数定義について、しらないのは初心者レベルではあるだろうと思いますが、別に初心者とか関係なく、順を追って理解したほうが説明がしやすいという話です。 関数の説明にifを登場させてifが何かわからないと言われたらうんざりするでしょう? 問題を解決したいのであれば質問者も回答者も協力すべきに私は考えています。 残すとかじゃなくて、プログラムのフローで理解したほうがいいと思います。 Rubyは設計者が機械の都合でコードを書きたくないという考えなので、基礎的なお約束事を理解するのが困難な可能性が高いです。基礎を理解している人で、特にプログラムを簡素に書きたい人向けの言語という立ち位置の認識です。 呼び出すというのは具体的には実行されたときの話です。一般的には。 a = 1+1というプログラムが記述されていても、何かのタイミングでこの文が呼び出されるタイミングが来ます。 普通、構造化プログラミングではこれを順次処理のタイミングで行います。 具体的に何に困っているのですか?極論関数が理解できなくてもプログラミングはできますし、理解できないならそのままでもいいとも思っています。 プログラムを書かないのであれば、関数の理解は必要がないように思えます。
utm.

2024/09/16 14:01

例えばデバッガでステップ実行するとか、printデバッグでどこがどのタイミングで実行されるのかを確認すればよいと思います。 デバッグとエラーは変数の代入よりも、一番最初に学ぶべき基礎中の基礎の認識です。 ほとんどの教材で無視される概念ですが、デバッグとエラーの学習をすれば、ほとんどの初心者プログラマは、新しい概念の理解について個人で勝手に学習を進められると思っています。
utm.

2024/09/16 14:03

ほかのコメントを一つ確認しましたが、やはり、「スコープ」と「ブロック」の概念について学ばれるとよいと思います。 すべての変数は別にグローバルスコープではないのです。 これは、初心者の直感と反する罠だと私も思いますので。
guest

0

これには2人の登場人物が居ると思ってください。

バイト「店長!800円のピザ3つでまとめ買い割引ありましたっけ?」
→menu1.get_total_price(3) ※def get_total_price(count)に問い合わせ

店長「ふむふむ、ピザ3つで2400円だな」
→total_price = self.price * count

店長「そして、3つ買うと、まとめ買い割引対象だから100円引きだね」
→total_price -= 100

店長「ピザ3つ買うと2300円だよ~」
→return total_price ※バイトに返答(戻り値)する

バイト「お客さんお待たせ!3つ買うと2300円になります!」
→puts menu1.get_total_price(3)

このreturnはrubyの場合は省略できますが、「書いた方がわかりやすい」って事で、当たり前の様に書いてます。

投稿2024/09/16 04:27

Black_Velvet

総合スコア74

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

basashitosushi

2024/09/16 08:07

本来であれば上から順にコードが処理されるのを 最初に一番下の「puts menu1.get_total_price(3)」を読み込んでから 一番上の「class Menu」から処理されるということですかね? 一番わかりやすいです!!!!! 「return total_price ※バイトに返答(戻り値)する」の後の処理がわからなかったので 自分なりに置き換えてみました。 ⑤店長がバイトに返答「ピザ3つ買うと2300円になるのを確認」のコード部分ですが、 「total_price」は③のコード「total_price」に2300円が代入されるということでしょうか? そうすると以下数字に置き換えられて800 * 3は2400だけど、途中経過で100円引きにされたから800 * 3 でも無理矢理2300円になるということでしょうか total_price = self.price * count 2300 = 800 * 3 ーーーーーーーーーーーーーーーーーーー class Menu attr_accessor :name attr_accessor :price def info return "#{self.name} #{self.price}円" end 店長 def get_total_price(count)  ②店長確認「800円のピザ3つでまとめ買い割引可能か確認」 total_price = self.price * count ③店長確認「ピザ3つで2400円であることを確認」 if count >= 3 total_price -= 100 ④店長確認「3つ買うと、100円引きになることを確認」 end return total_price ⑤店長がバイトに返答「ピザ3つ買うと2300円になるのを確認」 end end menu1 = Menu.new menu1.name = "ピザ" menu1.price = 800 バイト puts menu1.get_total_price(3) ①800円のピザ3つでいくらか店長に聞く
Black_Velvet

2024/09/16 08:36

まぁ、この場合、Class Menuが店長にあたりますね。 つまりmenu1《店長へ》.get_total_price(3)《値段確認》って事です。 Menu.newが読まれない限りClass Menuの部分はいわゆる「スキップ」されます。 Menu.newが読まれて初めて店長が登場します。 その為、menu1 = Menu.newで店長を登場させてからmenu1.get_total_price(3)で店長に値段を確認しているということです。 >⑤店長がバイトに返答「ピザ3つ買うと2300円になるのを確認」のコード部分ですが、 「total_price」は③のコード「total_price」に2300円が代入されるということでしょうか? そうすると以下数字に置き換えられて800 * 3は2400だけど、途中経過で100円引きにされたから800 * 3 でも無理矢理2300円になるということでしょうか 簡単に言えばそういうことです。 if count >= 3 total_price -= 100 end があるので、無理矢理ではなくそういうルールなんでしょうが、「ある数字を渡すと、それに対する返答がある」というのがdef(関数)というものです。 これが3個以上なら100円引きですよってことなので5個なら4000円-100円で「3900円だよ」という店長の返答があります。 ちなみにputs menu1.get_total_price(3)は「800円のピザ3つでいくらか店長に聞く」と「店長の返答をお客さんに伝える」がセットになっているので、 answer=menu1.get_total_price(3) 800円のピザ3つでいくらか店長に聞く put answer 店長の返答をお客さんに伝える と考えると分かりやすいかもですね
basashitosushi

2024/09/16 13:45

コメントありがとうございます!! 少しずつ質問させてくださmmmmmm >Menu.newが読まれて初めて店長が登場します。 こちらですが、Menu.newが読まれるというのがよくわからずでして、 例えば店舗のタッチパネルでピザが注文された時、という意味であっていますかね、、 >Menu.newが読まれない限りClass Menuの部分はいわゆる「スキップ」されます。 というのは、注文されない限り以下コードの部分がスキップされるという意味でしょうか attr_accessor :name attr_accessor :price
Black_Velvet

2024/09/17 03:08 編集

大前提としてbasashitosushi様が最初に仰られた様にコードというのは上から順番に読まれていきます。 >こちらですが、Menu.newが読まれるというのがよくわからずでして、 例えば店舗のタッチパネルでピザが注文された時、という意味であっていますかね、、 注文されたときというか、この物語に登場させるということです。 物語の途中で急に知らない人が話し始めるなんてことないですよね? まず、店長を「登場」させるのです。 そのあと、バイトと店長の会話が始まります。 このコードでは「タッチパネルで注文をしたとき」の部分は無く、あるとするならこのコードよりも前の話です。 あくまでこのコードでは「店長を登場させてまとめ買い価格を聞く」~「お客さんに割り引いた金額を伝える」までの物語です。 >Menu.newが読まれない限りClass Menuの部分はいわゆる「スキップ」されます。 というのは、注文されない限り以下コードの部分がスキップされるという意味でしょうか もっとです。 class Menu attr_accessor :name attr_accessor :price def info return "#{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 ここまでです。 def infoとdef get_total_price(count)は「店長(class Menu)へ聞く事ができる事(関数)」です。 なので、 ①class Menuを一旦スキップ ②店長を登場させる Menu.new ③店長にピザとピザの価格を言う menu1.name = "ピザ" menu1.price = 800 ④それらを3つ買った時の価格を問い合わせる menu1.get_total_price(3) という流れです。 私はRubyできないので詳しく分かりませんが… 「なんで?」思うかも知れませんが、恐らく先にスキップさせてからMenu.newをしないとエラーになりますのでスキップという行動が存在しています。(スキップというのは別に専門用語ではなく分かりやすく言ってるだけですので他のプログラマに言うと笑われます。)
guest

0

>①戻り値とはなんのどこにある値がどこに戻るのでしょうか?
メソッドの処理結果を呼び出し元に返します。

>②ソースコードの return total_price はなんのためのコードでしょうか。
>また、total_priceはどこに戻るのでしょうか。
>total_price の結果はtotal_price -= 100で出てるのになぜ
>return total_priceが必要なのでしょうか
puts メソッドに計算結果を返し、コンソール出力しています
返り値がないと、putsメソッドに計算結果を渡せず、コンソール出力できません

>③return total_priceがあってもなくても同じ結果になるのは何故でしょうか
Rubyはreturnを省略するとメソッドの最後に記述した式が戻り値になるという仕様です
返り値を明示するために、省略しないのが一般的かと思います。

投稿2024/09/15 21:23

pea

総合スコア453

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

maisumakun

2024/09/16 07:48

> 返り値を明示するために、省略しないのが一般的かと思います。 少なくとも、メソッド末尾で(値は明示しても)returnは書かない流儀もよく見かけます。
basashitosushi

2024/09/16 08:21

ありがとうございます! まだわからないことがあり質問させてください! >①戻り値とはなんのどこにある値がどこに戻るのでしょうか? >>メソッドの処理結果を呼び出し元に返します。 呼び出し元というのはコードでいうと「total_price = self.price * count」の部分でしょうか? 呼び出し元というのが誰に対しての呼び出しなのかわからないです。 >①戻り値とはなんのどこにある値がどこに戻るのでしょうか? メソッドの処理結果を呼び出し元に返します。 >②ソースコードの return total_price はなんのためのコードでしょうか。 >また、total_priceはどこに戻るのでしょうか。 >total_price の結果はtotal_price -= 100で出てるのになぜ >return total_priceが必要なのでしょうか >>puts メソッドに計算結果を返し、コンソール出力しています >>返り値がないと、putsメソッドに計算結果を渡せず、コンソール出力できません puts メソッドには「menu1.get_total_price(3)」と記述されており、total_priceのコードはないので、なぜputsに計算結果が返されるのかがわかりません。 ーーーーーーーーーーーーーー class Menu attr_accessor :name attr_accessor :price def info return "#{self.name} #{self.price}円" end 店長 def get_total_price(count)  ②店長確認「800円のピザ3つでまとめ買い割引可能か確認」 total_price = self.price * count ③店長確認「ピザ3つで2400円であることを確認」 if count >= 3 total_price -= 100 ④店長確認「3つ買うと、100円引きになることを確認」 end return total_price ⑤店長がバイトに返答「ピザ3つ買うと2300円になるのを確認」 end end menu1 = Menu.new menu1.name = "ピザ" menu1.price = 800 バイト puts menu1.get_total_price(3) ①800円のピザ3つでいくらか店長に聞く
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.39%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問