メソッドの呼び出し回数をカウントする
メソッドを呼び出した数を出力する関数を作りたいと思っていますが、思うようにかけません。
例えば、メソッドを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
試したこと
単にインスタンス変数を使うだけでは、ダメでした。
どのようにしたらいいでしょうか。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答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
総合スコア8560
0
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 を利用してメソッド呼び出しをログに記録させる
投稿2018/08/28 15:21
総合スコア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 では クラス変数って呼ばれているみたいですが。
投稿2018/08/28 09:32
編集2018/08/30 01:37総合スコア4958
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/08/28 23:41