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

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

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

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

Q&A

解決済

4回答

988閲覧

Rubyにおいてインデントが深くならないキレイな書き方を教えて下さい。

yuki_90453

総合スコア326

Ruby

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

1グッド

2クリップ

投稿2019/05/29 02:51

いつもお世話になっております。

###背景
ちょっとした単純作業を効率化すべき主にRubyでコードを書いています。
CSVやJSONを取り扱うことが多く、コードを書く際、if や for を多様します。
そうするとインデントが深くなってしまいコードがとても見にくくなってします。
エディターをブラウザと分割して表示しており、エディターの横幅に限界があります。

###試したこと
そこで私がとっている対策は、長いコードを何分割かにして関数化しています。
動作1→動作2→動作3という感じに関数化し分割しています。
しかしこれでは分割し関数化にしたコードを再利用しませんし、使い方が間違っていると思い腑に落ちません。

###質問

  1. インデントが深くなることは、良くないことなのでしょうか?

私にはコードが見づらいので、インデントを多様することにメリットを感じません。

  1. forやifを多様せず、効率よく書く方法はないのでしょうか?

JSONを扱っているとfor-if-forのように入れ子になるケースが多くと感じます。

  1. ユーザースクリプトを主に書いております。長いコードは、文章のように上から下へコードの流れを書くのが可読性が高いと思っています。

ただ長くなってしまうとインデントが雪だるま式に増えてしまいます。何か対策はないのでしょうか?

DrqYuto👍を押しています

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

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

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

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

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

nskydiving

2019/05/29 03:57

コードによってやり方が変わってくると思いますので、インデントが深いと感じていらっしゃる具体的なコードを提示していただけますでしょうか。
stdio

2019/05/29 09:10 編集

C++などではどうしてもインデントが深くなってしまう事が多々あります。 その上JSONのデータは多重リスト形式になっている事が多い為、インデントが深くなってしまう又は事は避けられないようなことも良くあります。この辺は再起処理で対応しても良いのですが、仕組みを理解していないと苦しい節があるのと、拡張性がなくなるのでおススメはしませんがインデント減らしには最適です。 あと、80文字で改行してくれるようなエディタもありますので使ってみるのも手かと思います。
guest

回答4

0

しかしこれでは分割し関数化にしたコードを再利用しませんし、使い方が間違っていると思い腑に落ちません。

メソッド化(関数化)の目的は再利用だけという訳では無いので、使い方は間違っていません。
メソッド化したときに、メソッドにわかりやすい名前を付けられるのであれば、そのメソッド化は有効で、コード全体の可読性を上げます。

投稿2019/05/29 13:17

otn

総合スコア84555

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

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

otn

2019/05/29 14:51

そういえば、「1つのメソッドで制御構造(ループとか、条件判断)は1つまで」という細かくメソッド分けるコーディングルールもあるようです。 これは、名前付けに苦しみそうですが。
guest

0

ベストアンサー

皆さんおっしゃってるように、インデントが深くなるのは読みにくいです。1画面に収まらないときなど、ここはどの階層??? と道に迷うことが多いです。
そのために再利用のないmethodに切り出すのも皆さんおっしゃるとおりです。

JSONてなんでもありなので、なんでもありな場合は使えませんが、質問のcodeをみると定義された構造を持ったJSONだと思われますのでその前提で。

わたしがよくやるのは以下のような方法です

def 第一階層の処理 前処理 第一階層の要素達.each case when ; 第二階層case1の処理 when ; 第二階層case2の処理 end end 後処理 end : : def 第123階層の処理 前処理 第123階層の要素達.each 第124階層の処理 end 後処理 end

投稿2019/06/08 20:51

winterboum

総合スコア23347

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

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

yuki_90453

2019/06/24 08:46

回答が遅くなってしまい申し訳ございません。 非常に参考になりました。 ありがとうございます!
guest

0

コードを見せていただけないとコメントしづらいですが、rubocopなどを使って解析してみらいかがでしょうか?

どうしたらベストかは人それぞれだとおもいますが、良い解決策が見えてくるかもしれませんよ。

投稿2019/05/29 16:22

odyu

総合スコア548

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

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

0

コードが無いと具体的には説明しづらいのですが、
データ加工の処理はループだけで書くと下のようになりがちですね。
メソッド分割したところで、ループ処理があっちこっちに行ってしまうと、見通しが悪くなりがちです。

ruby

1loop { 2 Aの処理 3 loop { 4 Bの処理 5 loop { 6 Cの処理 7 } 8 } 9}

(loopのとこはwhileだったりするかもしれませんが。)

こういうときは、Enumerableにあるメソッドで、一括して処理してあげると、ネストが深くならずに書くことができます。
処理が増えても、下へ下へ伸びるだけですし、メソッド化しても大きな流れを見失うことは無いかと思います。

https://docs.ruby-lang.org/ja/latest/class/Enumerable.html

ruby

1対象のデータ. 2 xxx { Aの処理 }. 3 xxx { Bの処理 }. 4 xxx { Cの処理 }

xxxの部分で呼び出すべきメソッドは処理の内容によっていろいろです。

単にループを回したいだけならeachだったり
値を変換する処理ならmap
if/unlessを置き換えるなら、selectやrejectなど。

処理内容が長くなりすぎてしまうと、読みづらいので、メソッド化するとよいです。
その際はぜひrubyの特徴であるブロックを使いましょう。
ブロック引数の使い方を学ぶといいです。
https://docs.ruby-lang.org/ja/latest/doc/spec=2fdef.html#method

Enumerableには、隣接する要素を加工する(each_slice)とか、二つの配列から値を組み合わせる(zip)とか、変わり種なメソッドもあります。
まずはリファレンスを眺めてみると良いのではないでしょうか。

投稿2019/05/29 10:50

takumiabe

総合スコア661

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問