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

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

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

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

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

Q&A

解決済

3回答

1211閲覧

メソッドをカウントする

3730

総合スコア9

Ruby

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

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

2グッド

2クリップ

投稿2018/08/28 09:08

編集2018/09/04 01:11

メソッドの呼び出し回数をカウントする

メソッドを呼び出した数を出力する関数を作りたいと思っていますが、思うようにかけません。
例えば、メソッドを3回実行すると、以下のように表示されるようにしたいです。

"1:Hello"
"2:Hello"
"3:Hello"

発生している問題・エラーメッセージ

"1:Hello"
"1:Hello"
"1:Hello"
で出力されます

該当のソースコード

Ruby

1def hello 2 count = 1 3 puts "#{@count}:Hello" 4 count += 1 5end 6 7hello 8hello 9hello

試したこと

単にインスタンス変数を使うだけでは、ダメでした。
どのようにしたらいいでしょうか。

ray_rio, DrqYuto👍を押しています

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

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

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

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

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

guest

回答3

0

ruby

1module Hello 2 @@n = 0 3 def hello 4 n += 1 5 puts 'hello %s' % @@n 6 end 7 module_function :hello 8end 9 10Hello.hello 11Hello.hello 12Hello.hello

投稿2018/08/28 11:49

mkgrei

総合スコア8560

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

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

3730

2018/08/28 23:41

クラス変数で、値を保持するやり方もあるんですね。 ありがとうございます!
guest

0

3つのプログラムを書いてみました。
実行結果
イメージ説明

hellow_1.rb

ruby

1$count = 0 2 3def hello 4 $count += 1 5 puts "#{$count}:Hello" 6end 7 8hello 9hello 10hello

hellow_2.rb

ruby

1class TraceX 2 @@count = Hash.new(0) 3 def self.count(name) 4 @@count[name] 5 end 6 def self.count_up(name) 7 @@count[name] += 1 8 end 9end 10 11def hello 12 TraceX.count_up(__method__) 13 puts "#{TraceX.count(__method__)}:Hello" 14end 15 16hello 17hello 18hello

hellow_3.rb

ruby

1$count = Hash.new(0) 2 3TracePoint.trace(:call) do |tp| 4 $count[tp.method_id] += 1 5end 6 7def hello 8 puts "#{$count[__method__]}:Hello" 9end 10 11hello 12hello 13hello

hellow_2.rb はグローバル変数を使用しないようにしています。
hellow_3.rb は、カウンターのアップ忘れを防止しています。
hellow_2.rb, hellow_3.rb は method をつかうことで、複数のメソッドの呼び出し回数の管理がしやすいようにしています。

hello_3.rb が短くてよいのですが、グローバル変数をつかっているのが...
hellow_2.rb のようにクラスを作って、クラス変数でカウンター情報を持つようにして、TracePoint 機能でカウントアップさせるのが良いかもしれません。

参考情報

  • Ruby の TracePoint について調べてみた

https://qiita.com/siman/items/9426ff6c113247088f7e

  • [Ruby] caller を利用してメソッド呼び出しをログに記録させる

https://qiita.com/katoy/items/a4dac843383185019f9d

投稿2018/08/28 15:21

katoy

総合スコア22324

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

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

0

ベストアンサー

まぁ、なんとなくわかるけど、

思うようにかけません。

とか

単に変数を使うだけでは、ダメでした。

じゃなくて、「何がどのようにダメだったのか」を明記してください。

趣味でも他人に聞くのだから相手にわかるように説明すべきです。仕事ならなおさらです。

多分、コードから妄想するに、

本来なら

1: hello
2: hello
3: hello

となってほしいのに

1: hello
1: hello
1: hello

とカウントアップされないっていうことですよね?

それならそうです。

変数と定数 (Ruby 2.5.0) を読むと、

"$" をつけるとグローバル変数, つけない場合はローカル変数となるみたいです。

ローカル変数は その関数の開始に確保されて終了の 例えばendみたいなところ(もしくはそこから抜けたところ) で破棄される。( スタック領域の場合。 )

だから

[一回目]:
開始: count = 1
表示部
終了前: count + 1 = 1 + 1 = 2
ブロックから抜ける
破棄

[二回目]:
開始: count = 1
表示部
終了前: count + 1 =...

とこれを延々と繰り返している感じ。
だからいつまでたっても1,2,3,4...みたいな状態にはならない。

どうしてもやるなら

方法1: グローバル変数を使う ( 危険!!!!!! 非推奨です。 )
方法2: 呼び出し元で管理し、hello関数を呼び出すときに引数として渡して 戻り値で取得

Ruby

1def hello(num) 2 # ここで表示 3 return num + 1 4end 5 6n = 1 7n = hello( n ) 8n = hello( n ) 9n = hello( n )

みたいにして
引数 -> 戻り値 -> 引数 -> 戻り値... みたいにする。

方法3: クラスのフィールドとして count に相当するものを保持してそこにアクセス ※ Ruby では クラス変数って呼ばれているみたいですが。

参考1, 参考2

投稿2018/08/28 09:32

編集2018/08/30 01:37
BeatStar

総合スコア4958

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

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

3730

2018/08/28 10:16

ご指摘および、回答ありがとうございます。 分かりやすく質問すること、どこまで理解しているかを明確にするようにします。 また、クラスのフィールドの方法を改めて勉強してみます。
BeatStar

2018/08/30 01:40

mkgreiさんへの返信読みました。 ああ、そうそう。クラス変数です。 フィールド = クラス変数 ですね。(追記しておきました。)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問