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

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

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

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

Q&A

3回答

1229閲覧

Ruby : メソッド定義について

ruby_11

総合スコア37

Ruby

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

0グッド

0クリップ

投稿2017/07/30 08:58

テキスト処理についてのコードです。

Rubyでテキスト処理をしているのですが、同じような繰り返しが2回あるので、なんとかメソッドにして綺麗にコードを書けないかなと思って、試してみましたがやはりメソッドを作ることを今までしてこなかったためどのようにすればいいのかわかりません。

また、メソッドにしなくてもうまく動くので、無理にメソッド化する必要はないと思いますが、せっかくなので、今後のためにもメソッド作成を学んでおきたいと思いました。

以下のコード内の、filename_so ~ 最初のif文のendまでと、filename_nso ~2つめのif文のendまでをうまくメソッドにすることはできないでしょうか?

コード内の、soとnsoをメソッドの引数に取り、呼び出しの際にsoかnsoかを示せば動くと思いましたが、うまく実行されませんでした。

例えば、以下のように、abcメソッドに対してpointを引数にとり、呼び出しの際に、abc("so")、abc("nso")と試してみました。

そもそもメソッド定義や引数に対する考え方や使い方が間違っているのでしょうか?

Ruby

1def abc(point) 2filename_"#{point}" 3end

Ruby

1require 'lemmatizer' # 動詞を現形にするライブラリ 2require 'active_support/all' 3lem = Lemmatizer.new 4 5Dir.chdir("../TOPIC") # TOPICフォルダへ移動 6 7topic_name = Dir.glob("*") #TOPICフォルダ内のフォルダを保存 8Dir.chdir("#{topic_name[0]}") # topic_nameの1番目のフォルダへ移動 9 10Dir.chdir("SO/SO_SCRIPT") #SOフォルダのSO_SCRIPTフォルダへ移動 11filename_so = Dir.glob("*") #SO_SCRIPTフォルダのファイルをfilename_soに保存 12if filename_so.count == 0 # filename_soの数が0個なら 13 puts "Empty..." 14else #0個でないなら 15 puts filename_so[0] 16 text_so = File.read(filename_so[0]) #filename_soの1番目のテキストをtext_soに保存 17 text_so.downcase!.gsub!(/\,|\./, '') #テキストの大文字の部分を小文字に置換し, ,と.を削除 18 text_so.gsub!(/\([a-z\s]+\)|\[[a-z\s]+\]|\'[a-z]+|\-|\—|\n|[0-9]+\:[0-9]+|[^a-z\s0-9]/, ' ') # ()と[]内の文字を空白に, 以降も同じように置換 19 text_so.gsub!(/\s+/, ' ') # 2個以上の空白を1つに置換 20 word = text_so.split # テキストを空白で区切りwordに保存 21 array = [] # 配列arrayを定義 22 word.each { |w| array << lem.lemma("#{w}").singularize } # word内の単語を現在形にし, かつ単数形にしてarrayに保存 23 array.sort! # arrayをソート 24 #puts array 25end 26 27Dir.chdir("../../NSO/NSO_SCRIPT") 28filename_nso = Dir.glob("*") 29if filename_nso.count == 0 30 puts "Empty..." 31else 32 puts filename_nso[0] 33 text_nso = File.read(filename_nso[0]) 34 text_nso.downcase!.gsub!(/\,|\./, '') 35 text_nso.gsub!(/\([a-z\s]+\)|\[[a-z\s]+\]|\'[a-z]+|\-|\—|\n|[0-9]+\:[0-9]+|[^a-z\s0-9]/, ' ') 36 text_nso.gsub!(/\s+/, ' ') 37 word = text_nso.split 38 array = [] 39 word.each { |w| array << lem.lemma("#{w}").singularize } 40 array.sort! 41 #puts array 42end 43

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

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

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

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

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

guest

回答3

0

Dir.chdir("SO/SO_SCRIPT")以下、と
Dir.chdir("../../NSO/NSO_SCRIPT")以下、
酷似しているなら(diff取ってないですが、全く同じ処理ですよね?)、
ここから共通化できると思います

共通化することで、変数名をfilename_so, text_so, filename_so, text_nsoは
2つに減らせます。

共通化する、so, nsoどっちの処理かわからない、
というなら、puts Dir.pwd などすればいいと思います(下記の末尾の方に記載してます)

ruby

1def abc(path) 2 Dir.chdir(path) 3 f_name = Dir.glob("*") 4 if f_name.count == 0 5 puts "Empty..." 6 else 7 puts f_name[0] 8 t = File.read(f_name[0]) 9 t.downcase!.gsub!(/\,|\./, '') 10 t.gsub!(/\([a-z\s]+\)|\[[a-z\s]+\]|\'[a-z]+|\-|\—|\n|[0-9]+\:[0-9]+|[^a-z\s0-9]/, ' ') 11 t.gsub!(/\s+/, ' ') 12 word = t.split 13 array = [] 14 word.each { |w| array << lem.lemma("#{w}").singularize } 15 array.sort! 16 #puts Dir.pwd 17 #puts array 18 end 19end

投稿2017/07/30 11:54

bamboorian

総合スコア34

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

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

0

書き換えてみました
提示されたコードのみを頼りに、想像する部分は考えずに書いたため、おおきな勘違いなどあるかもわかりません

基本的に:

  • 単純に処理が重複する部分
  • 「何がしたいか」が(ちょっとだけ違うけど)同じ処理

は、メソッドとして切り出すことができると思います

ruby

1require 'lemmatizer' # 動詞を現形にするライブラリ 2require 'active_support/all' 3 4def file_name_list(script_type:) 5 # TODO: このメソッドの呼び出し順序でカレントディレクトリが固定的に変化するか検証 6 case script_type 7 when :so_script 8 Dir.chdir('../TOPIC') 9 10 topic_names = Dir.glob('*') 11 Dir.chdir("#{topic_names.first}") 12 13 Dir.chdir('SO/SO_SCRIPT') 14 when :nso_script 15 Dir.chdir('../../NSO/NSO_SCRIPT') 16 end 17 18 Dir.glob('*') 19end 20 21 22def convert_text_to_words(file_name) 23 lem = Lemmatizer.new 24 25 text = File.read(file_name) 26 words = 27 text.downcase 28 .gsub(/\,|\./, '') 29 .gsub(/\([a-z\s]+\)|\[[a-z\s]+\]|\'[a-z]+|\-|\—|\n|[0-9]+\:[0-9]+|[^a-z\s0-9]/, ' ') # ()と[]内の文字を空白に置換 30 .gsub(/\s+/, ' ') 31 .split 32 words.map { |w| lem.lemma(w.to_s).singularize }.sort # word内の単語を現在形 かつ単数形に変換 33end 34 35# SO スクリプトの読み込み・変換処理 36file_names_so = file_name_list(script_type: :so_script) 37if file_names_so.count.zero? 38 puts 'Empty...' 39else 40 puts file_names_so.first 41 array = convert_text_to_words(file_names_so.first) 42 # puts array 43end 44 45# NSO スクリプトの読み込み・変換処理 46file_names_nso = file_name_list(script_type: :nso_script) 47if file_names_nso.count.zero? 48 puts 'Empty...' 49else 50 array = convert_text_to_words(file_names_nso.first) 51 puts file_names_nso.first 52 # puts array 53end

コメントの書き方についてですが、1行1行の処理についてではなく、「それらをすることによって何が起きるのか」の説明が書かれていると、初めて読む際に分かり易しいのではないかとおもいました(もちろん、この質問のために詳細に書かれたのでしょう)

何か参考になれば幸いです

投稿2017/07/30 11:24

編集2017/07/30 11:28
gouf

総合スコア2321

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

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

0

def abcの引数をDir.glob("*") の結果にして、中身の処理を
「filename_so ~ 最初のif文のendまで」にする
というのはどうでしょうか。

Ruby

1def abc(input) 2 filename_nso = input 3 以下略 4end

使うときは

Ruby

1data = Dir.glob("*") 2p abc(data)

みたいな感じです。
恐らく、array.sort!の結果が返ってくると思います。

投稿2017/07/30 11:11

編集2017/07/30 11:19
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問