TONY0922のブログ

学んだことを適当に記録していくブログです。主にRubyで仕事してます。最近はJavaScriptとObjectibe-C始めました。Titanium関連もちょいちょい触ってます。更新頻度はそんなに高くないので、ご了承下さい。

Xにてっとり早く上がるためにXプレイヤーにアンケートを取ってみた話

Splathon Advent Calendar 15日目です。

adventar.org

S+0に到達してから、はや半年間、S〜S+0を行き来しているので、
Xにてっとり早く上げるためにXプレイヤーの思考を身につけられれば良いのでは?
という安直な考えのもと、アンケートを取ってみました

とある、コミュニティのXプレイヤーの方にアンケートを募ったところ
なんと、51名のXプレイヤーの方々からご回答を頂いたので、この場で集計結果を公表しようかなと思います。

ちなみにXプレイヤーの定義は「ウデマエXのルールを一つ以上保持しているプレイヤー」を指します。

あなたの最高Xパワーは?

XP 割合
2100 ~ 2300 33.3
2300 ~ 2500 52.9
2500 ~ 13.7

2500 以上でも、13.7% (6名)いるのかー。

あなたの最高Xパワーのルールは?

ルール 割合
ガチエリア 52.9
ガチヤグラ 19.6
ガチホコ 17.6
ガチアサリ 9.8

やっぱり、一番ルール理解がしやすいエリアが多いんすねー。

スプラトゥーン1のプレイ時間は?

プレイ時間 割合
やってません。 17.6
~ 500h 5.9
~ 1000h 15.7
~ 1500h 23.5
~ 2000h 19.6
2000h ~ 17.6

全体約6割は1000h以上やりこんでるんすねー。
(こないだやっと1000h超えた)

X(S+10)に到達したときのSplatoon2の総プレイ時間はざっくり言うと?

プレイ時間 割合
~ 500h 39.2
~ 1000h 49
~ 1500h 7.8
~ 2000h 2
2000h ~ 2

X(S+10)に到達した一番最初のルールは?

ルール 割合
ガチエリア 51
ガチヤグラ 27.5
ガチホコ 17.6
ガチアサリ 3.9

やはり、エリアが多い!

S+帯プレイヤーを手っ取り早くXに到達させるオススメのルールをあえて言うなら?

ルール 割合
ガチエリア 43.1
ガチヤグラ 27.5
ガチホコ 23.5
ガチアサリ 5.9

ですよね〜。

(任意項目)上の答えのその理由を簡単に説明すると?

ガチエリア

  • オブジェクトが固定されていて、他ルールよりも状況判断がしやすいため。
  • ルールが単純だから(ヤグラ・ホコ・アサリの順に複雑)
  • 講座・解説動画などで採用されていることが非常に多いため、学んだ事を活かしやすいはず
  • オブジェクトが中央に一つだけだからか個人的にはスペシャルをためて味方を待ちやすかったため(?)味方を待つゆとりが比較的ある気がしているため(?)
  • ホコやヤグラよりも明確な強武器がないように感じるのと、打開、前線維持の抑えるべき要点が他に比べて少なくパターン化しやすく思うので。
  • 上達に対して素直に反応してくれるから
  • 自分の中で楽しいから
  • 立ち回りがわかりやすい
  • 勝つための道筋がわかりやすい
  • オブジェクトが1番わかりやすいため
  • 最も対面以外の要素が勝敗に影響するルールだと思っているため
  • 敵を倒す事が勝ちにつながるシンプルな答えがあるから、他にもありますが、、
  • X帯の人数が一番多い気がする(S+が相対的に弱い)
  • ルール把握が簡単
  • オブジェクトが固定であり、攻めと守り(抑え)のターンが明確に分かるから
  • 覚えるべきステージ上の要所が少なく、打開や固めなどそれぞれの状況で強い行動がわかりやすいので、やるべきことを覚えやすい。
  • オブジェクトが固定されてて、ステージ毎の立ち回りの型を作りやすいから。
  • 考えることが少ないため。長射程で死なずにエリアを塗って、味方をサポートすることをメインに考えるだけで大丈夫。
  • 消去法
  • 同じパワーの平均的なレベルが低い
  • 個人の力でなんとかなりやすいから(他ルールは連携力が問われがち)

ガチヤグラ

  • ヤグラに乗ってれば勝てるから
  • オブジェクトに関わりながらキルを取るのが楽
  • 単純に「ヤグラだけX」みたいな人が多いイメージ
  • 守りに集中してヤグラに乗ってる人を倒せば負けないから
  • 状況判断の要求水準が低い。キル取れなくてもヤグラ乗ってれば勝てるなど、必要なスキル種類が少なくて、学習しやすい。
  • オブジェクト管理できない味方がいてもある程度自分でコントロールできるから
  • Xまではヤグラに敵が集まってくるので守りやすい
  • オブジェクト管理をしっかりすれば勝てる
  • ゲームスピードが他より遅く一発負けにならず試合を立て直しやすい
  • 一番一人で何とかできるルールだと思う。攻めるとき一人で敵を倒しながらカウント進め安いルールはエリアとヤグラ。鉾持ちでカウントは進められるとは言え、鉾で倒しながらってのは難しい。アサリは常に前線いてもアサリも集めないとカウント進まなないので却下。で進めるだけでなく守る場合一人で守れるかを考えるとヤグラの方が敵位置把握しやすいから敵を倒して人数有利とりやすいのと、カウントも止めやすいから。エリアで打開と考えた場合、間違いなく潜伏はいるし、敵を数人落としてからじゃないとエリア濡れないし、でも味方はSP貯めないでっ込んでいくしで、打開のしやすや(ってよりカウントの止めやすさ)はヤグラだと思う。
  • エリア、ホコに比べ武器編成で試合が決まりにくい(霊感)
  • S+だと櫓だけを見る人が多いので、櫓の前で潜伏や圧力をかける動きが刺さりやすいのでオススメです。またブラスターやハイプレ持ちの強さがはっきりしてるのでこだわりがなければ武器を選ぶだけで勝率がそのまま上がると思います。
  • ある程度コツでなんとかできるルールだから

ガチホコ

  • キルとれなくてもホコ管理でかなり貢献できるから
  • ホコの持ち方さえ覚えれば、対面弱くても相手の武器が何であろうと関係なく勝てる(かもしれない)から
  • 逆転がエリアとかヤグラに比べると容易かも…?
  • ルールを理解すれば対面力はさして要らないため
  • ポイントを抑えると、一定レベルまで勝ちやすい
  • オブジェクト意識だけで勝率5割に届くので。
  • ルールがわかりやすい。比較的相手の攻めを止めやすい。自分の体面の強さが勝利に直結しやすい"
  • 最重要オブジェクトの管理を自分の判断で行いやすく、仕事量を高めやすいため(=自陣ホコ塚から遠い場所- にホコを押し付けての遅延行為など)。立ち回りと撃ち合い技術(エイム・キャラコン)をあせらず磨けばX上がれるゲームだと思いますが、後者は才能の部分もあるので、知識で勝ち筋を太くしやすいルールを挙げました。
  • 対面で無双するだけで勝てる
  • 攻め守りがはっきりしていて考えることが少ないから
  • 周りがアレでも自分が頑張ればなんとかなる唯一のルールかもしれない

ガチアサリ

  • プレイ人口が少ない。キルとれなくても立ち回りだけでどうにかなるので。
  • プレイヤー人工が少ない気がしていて、Xパワーも比較的上がりやすい気がするから
  • アサリは治安がいい

X(S+10)に到達したときによく使っていたブキは?

ブキ 投票数
スプラシューターコラボ 9
N-ZAP85 6
デュアルスイーパーカスタム 4
パラシェルター 4
クラッシュブラスター 3
スプラシューター 3
スプラローラー 3
バレルスピナーデコ 2
ホットブラスター 2

やっぱりスシコラ強い! 意外なのは、マニューバーがいないことだね。 時期によっては弱かったんだろうか...

X(S+10)に到達したときに録画機材(キャプチャボード)とか買って振り返りしてた?

振り返りした? 割合
録画機材で振り返りしてました。 72.5
録画機材持ってなかった。 27.5

結構持っていない人多いんですねー。

(任意項目)Xに到達するために一番手っ取り早い方法があるとすれば何だと思いますか?

  • 長射程武器を持って、射程管理を覚える
  • 解説が上手い人の動画を観て、考えながら量をこなす。あと知り合いの強い人に実際のプレイを観てもらいアドバイスをもらうとか。
  • 上手い人の配信や動画を見て動きや状況判断を学びつつ、Xの人達とリグマやプラベをしてアドバイスを貰う。
  • ルールとステージを厳選する。具体的に言うと自分の武器と立ち回りをルルステに合わせて変えるのはしんどいので、自分の武器と立ち回りで勝てる組み合わせで勝負する。ただしXに行ってから苦労する
  • 上手い人の動画を見る
  • 自分の選択で避けられるリスクを最初から避ける(やけくそになって連戦する・長射程(編成事故の一因になる)ブキをもつ・海外勢とマッチングしやすい時間に潜るなど)
  • 自分に合うブキ選びとそのブキの能力を活かせる立ち回りを身につけること…?
  • あわてないだけでいい
  • AIMで勝負しないタイプのうまい人のプレイ動画を参考にする
  • youtuberの上手い人の動画をひたすら見て立ち回りと状況判断を勉強する
  • Youtubeとかで打開時の動き方や抑えの動き方を解説してる人の動画をみて一旦真似てみながら試行錯誤して自分にあったやり方を発掘していくといいんじゃないかなと思います
  • 同じ武器を持っている有名プレイヤーの動画を見て初動や展開の動きの真似。
  • エリアのエクスロでとにかく負けの確立を減らすことだけを考えた立ち回りをする。
  • 上位勢のプレイを見る
  • 振り返りとかしたくないなら対面力上げる、そうじゃないなら立ち回りのPDCAまわす
  • リグマ・プラベでx帯と多く対戦するのが早道かと
  • 前線であばれて常に人数有利つくる
  • ガチマッチ
  • 人数ゲージとスペシャルをみて攻め時守り時を理解する。対面/索敵力を人並みにつける 振り返りは重要だと思います。エイム感度、インク使用量などの感覚調整はした方がいいなと思うのと、キル取る人でなければ守る方法を自分スタイルで確立するとか、自分として勝てるスタイルを持つのが重要だと思います。
  • 自分のプレイを録画してフィードバックもらう
  • ガチエリアで以下2つを意識することだと思います。・完全打開の際にスペシャルを合わせる意識を持つこと・人数有利の時に積極的に戦うこと。対面に自信があるなら、ホコで無双すればよし。
  • 消極的なプレーをしない事、結局個人能力は上がらないので
  • 得意武器でオブジェクト意識して戦う
  • オブジェクト意識を持つ
  • 考えてプレイする
  • ゲームプランを持つ
  • うまいプレイヤーの動画を見る。自分のプレイ動画を撮って、自分で見直し比較する。また、添削を受ける。
  • 連勝しようとせず、勝率5割を維持することにだけ意識を向ける。
  • 使用武器を固定する、ルールをきちんと理解する、ステージをきちんと理解する、状況に応じて最適な行動を取れるようにする。
  • 得意なルールとステージを狙ってプレイすること
  • 逆に考えるんだ、「(カウントを)あげちゃってもいいさ」と考えるんだ。S+帯はカウントがリードされそうになると焦ってオブジェクトに集まる傾向があって、それだと順番に倒されて結局致命傷のカウントをもらうことになる。それを避けるために時間がまだ十分あるなら、一旦のリードはあきらめて死なずにどのルールでもSP貯めてちゃんと打開(人数有利)をとってしっかりこっちのターンにすることを意識する。逆に相手は突っ込んでくるので、一人ずつ順番に狩ればOK。これは手っ取り早くないか・・・。手っ取り早いのはクラブラ持ってヤグラ潜ってるだけでXなら行けそう?間合いにさえ入ればエイムなくても倒せるし、S+なら相手もエイムないので相手が弾当てきるまえにパンパンで倒せそう。
  • スペ減を積む(0.2以上)
  • 自分よりウデマエが上のプレイヤーと一緒にプレーすることで、改善点のフィードバックをもらったり速いゲームスピードになれること。
  • 環境見つつ、ステージもしくはルール的に強いブキをちゃんと考えて選ぶことだと思います。ヤグラならスペ減ガン積みプレッサー持つ、ホコならバリア即割りできる対物ブキ持つ、アサリならキャンプ持つとか。ちなみにエリアは基本ができてないと勝率が一番安定しないルールだと思います。
  • 味方の攻撃がかかっている場所で一緒に攻撃することを意識する。
  • Xの人のガチマ動画見て立ち回りの勉強。
  • 対抗戦とかで自分よりも強い人たちとガチマッチを繰り返して振り返りをしたり、YouTubeなどを観て強い人の動きを繰り返し観て、自分でもその動きができるように心がけながらプレイする。
  • 立ち回りより対面スキル重視
  • 丁寧にプレイする
  • 長射程エリアで得意なステージの時のみガチに潜る。
  • 対面力に自信があるならゾンビギアで櫓より前に出て横から刺す動きを意識する。対面力に自信がなければスペ減をつけて相手の櫓が関門にきた or こちらがカウント勝ってなくて攻めてる時以外ではハイプレを打たないようにするを意識する。また最近始めたのですが録画して振り返るのはめっちゃオススメです。
  • そもそもXに行ってない人、先に武器ありきで立ち回り決めてるけど、やりたい立ち回りにしたがって武器決める方がいい。 厨ブキを使う
  • 努力・友情・勝利。ごめんなさい嘘です総プレイ時間の多さでどうになる可能性は高いです
  • なるべくエイムがヘタクソな上級者の立ち回りコピー。エイムは時間かけないとどうしようもないので、立ち回りをなんとかする
  • 徹底して苦手ステージの時間帯のプレイを避けること
  • 放送して、強い人に判断思考基準を教えてもらって、取り入れる

やはりうまい人の動画みて、立ち回りを覚える方が多そう。

最後に

51名の方の回答を頂きまして、めちゃくちゃ参考になりました! 集計を終えてから、もっとあれこれ聞けばよかったなーと思いつつ、 また何かの企画でアンケート取るかもしれません!

事業会社に転職して半年経ったので、ふりかえり

今年の頭に中小SIerから事業会社に転職をして、
半年以上経ったので、振り返えりを書こうと思う。

なんで転職したか?

Sierで受託開発の仕事をしている間に
個人で小さなWebサービスをいくつか作った事があり、
それを周りの人につかってもらったり、そのサービスを大きくしていく上で、
BtoCの受託開発も良いけど、自社Webサービスをグロースさせる仕事も
面白そうだなーという気持ちが徐々に強くなり、転職を考えるようになった。

結果、去年の末にとある事業会社から内定をもらったので、転職することにした。

事業会社に転職でどうだったか?

「技術はあくまで手段であって、プロジェクトのKPIにコミットできないエンジニアはいらないよ。」
最初に上司に言われた言葉がこれだった。

恥ずかしい話だが、
入社する前は、事業会社のエンジニアの仕事って
企画サイドが考えた施策を開発者が実現可否やスケジュールを判断し、
自社メンバーで開発を進めていくものだと思っていた。

つまり、プロジェクトの売上を伸ばす施策は企画サイドが考え、
開発サイドはあくまでシステム開発を、いかにスピード感を持って、進めていくかに
コミットするものと思っていた。

が、実際には違った。

まず、エンジニアもプロジェクトの色んなKPIのどこかにコミットする必要があり、
その上でどんな機能を実装すれば、売上が上がりそうかをプロダクトオーナーやプロジェクトリーダーに
提案をし、開発を進めていくフローになっていた。

なので、プロジェクト内の色んなデータを集めて、分析して、どこにKPIが上がる余地があるかを見つけ、
提案資料を作成して、合意取って、やっとこさ要件定義や開発に入れるわけだ。

ただ、基本的には開発は社内常駐の業務委託の方にお願いすることがほとんどなので、
実際に自分で手を動かして、実装する機会がほとんどなく、エクセルやパワポを使う日々がここ暫く続いている。
(もちろんコードレビューやちょっとしたスクリプトを書いたりはする。)

なので、最近は技術書よりも「仮説思考」やら「ロジカルシンキング」やら「定量分析」などの
ビジネス書を読む機会が増えている。

事業会社なので、受託開発時代みたいに納品さえできれば、お金もらえるスタイルではなく、
あくまでサービスが伸びないと売上は発生しないので、
「エンジニアも売上にコミットしろ!」と言われるのは妥当なのかも知れない。

今後は自分の動き方次第では、企画をしつつ、コーディングも自分でやれそうなので、
歯を食いしばって、自社サービスをグロースしていこうと思う。

3回目の転職活動で利用した転職サービスの雑感

転職(その2) Advent Calendar 2016 11日目の記事です。

久しぶりに転職活動を行ったので、その雑感を書いていきます。

筆者のスペック

RubyJavaでシステムの受託開発がメインで要件定義 〜 開発まで一通りやらせてもらった。
いままでは受託オンリーの仕事をしており、事業会社でのエンジニア経験も積みたかったので、転職を決めた。

転職エージェントは使えるか?

使おうかどうか迷ってたが、結局今回も2社ほどお願いした。

1社は今の会社の転職でもお世話になった転職サービス大手のI社だ。
もう一社はヒカリエに本社を構えるエンジニア転職に特化したR社である。

R社に関しては、エンジニア転職をメインに行っていると聞き、技術的なところも理解した上で色んな会社を紹介してくれると期待したが、エージェントの技術的な知識が皆無で、I社にくらべて、R社を利用するメリットが無いと感じた。

そんなわけで最終的にR社は切ってしまった。

後、今回は年収を上げることも目的としてあったのだが、これに関してはどちらのエージェントも態度が消極的だった印象がある。
本音を言うと、年収upの戦略や助言みたいなのも期待していたので、残念だった。

転職ドラフトも使ってみたよ。

https://job-draft.jp/

これも3回くらいドラフトに参加した。
ありがたいことに色んな企業から面接のオファーを頂くことも出来た。
このサービスは自分の経歴を企業側が読んで、予め想定年収を提示してくれるため、終盤のメンドクサイ年収交渉をある程度スキップできるところが非常に良かった。
興味がある会社から面接オファーが来ても、提示年収が低ければ、断ることもできるので、余計な労力を使わずに済んだのは非常にありがたかった。

また、ある会社が他のエンジニアにどれくらいの年収でオファーを出すのかも分かるので、その会社の年収相場みたいなものも分かるのが良かった。
これにより、興味はあるが、年収相場があまりにも低い企業を発見できたりと、色々調査できるのが面白い。

最後に

最終的にエージェントを通して、転職が決まったが、個人的には転職ドラフトは大きくなってほしいサービスだと思っているので、次、もし転職する機会があれば、また使ってみたいとは思っている。

iTerm + tmux 使用時にvimの色設定が反映されない。

iTrem と tmux 使用時にvimrcで設定した色設定が反映されなかった時は、 下記の設定を行うと良い。

zshを使用しているが、bashでも同じと思われる。

alias tmux="TERM=screen-256color-bce tmux"
set -g default-terminal "xterm"

最後に反映を忘れずに。

$ source ~/.zshrc

参照URLはこちら

【Objective-C】翌日の指定時間のNSDateを取得する。

翌日の指定時間を取得したかったので、色々調べた結果 下記のような感じで書けそう。

NSDate* date = [NSDate date];
NSCalendar *calendar = [NSCalendar currentCalendar];

NSDateComponents *dateComps = [calendar components:NSYearCalendarUnit |
                               NSMonthCalendarUnit  |
                               NSDayCalendarUnit    |
                               NSHourCalendarUnit   |
                               NSMinuteCalendarUnit |
                               NSSecondCalendarUnit fromDate:date];
// 例)翌日の20:00を取得したい。
[dateComps setDay:(dateComps.day + 1)];
[dateComps setHour:20];
[dateComps setMinute:0];
[dateComps setSecond:0];

NSDate * notification_date = [calendar dateFromComponents:dateComps];
NSLog(@"date: %@", notification_date);
date: 2014-06-19 11:00:00 +0000

リファクタリング:Rubyエディション を読んだ。 〜 6章まで

リファクタリング:Rubyエディション

リファクタリング:Rubyエディション

久しぶりにリファクタリングについて勉強したくなったので、 読んで、重要と思った部分をメモ書きする。

第1章 リファクタリング

一時変数をメソッドリファクタリングする際にパフォーマンスの低下が懸念されるかもしれない。(P41)

  • そんなに問題にならないケースが多い。
  • できるだけ、リファクタリングは保守性を重視して、読みやすく変更を加えてやるべき。
  • 一時変数は無用に多くの引数をやりとりする原因になる点でない方が良い。
  • 一時変数を取り除けば、コードが何を使用としているのかがはっきりと分かるようになる。

※ 実際は一時変数をメソッドに置き換えて、リファクタリングをする人がどれくらいいるのか調べてみても良いかもしれない。

リファクタリングの問題点

インターフェースを公表済みの場合

  • 公表済みのインターフェースをリファクタリングをするのは、それの周知にコストがかかる。
  • したがって、普通は旧インターフェースと新インターフェースを両存させる。

第6章 メソッドの構成

メソッドの抽出

コードの断片をメソッドにして、その目的を説明する名前をつける。

利点

  • メソッドの粒度を細かくできれば、再利用しやすくなる。
  • 高水準のメソッドがコメントの連続のような感じで読みやすくなる。

Tips

  • コメントは抽出できるメソッドを見分けるのに使えることが多い。また、コメント自体が抽出されたメソッドの名前の候補になる。

一時変数から問い合わせメソッド

式をメソッドにする。一時変数の全ての参照箇所を式に置き換える。新しいメソッドは他のメソッドからも使える。

利点

  • 一時変数はローカルスコープのため、アクセスしようとするとメソッドを長くする以外に方法がない。したがって、問い合わせメソッドに置き換えれば、クラス内の全てのメソッドからアクセスできるようになる。

一時変数からチェインへ

チェイニングをサポートするようなメソッドに書き換え、一時変数を不要にする。

利点

  • 不要な一時変数を削除できる。
  • 自然に読めるようにコードを組み合わせられるインターフェースが増えるので、保守性が向上する。

Tips

  • チェイニングできるようにしたいメソッドからはselfを返すように実装する。
  • 一つのオブジェクト内でチェインは完結させたほうが良い。そうすることによって、表現力を高めることができる。

説明用変数の導入

処理の目的を説明するような名前を持つ一時変数に式、または式の一部の結果を代入する。

利点

  • 複雑な条件式が読みにくい場合は一時変数を使えば、式を管理しやすい形に分解出来る。

Tips

  • 一時変数はあくまでそのメソッド内のコンテキストでしか使えないため、できるだけメソッドの抽出を利用した方が汎用性は高い。

一時変数の分割

代入毎に別々の一時変数を用意する。

利点

  • ループ変数や結果蓄積用変数でないにもかかわらず、同じコンテキスト内で同名変数を使用すると、読み手が混乱するため、必ず別々の変数名を用意すること。

メソッドからメソッドオブジェクトへ

メソッドの抽出」ができないようなローカル変数の使い方をしている長いメソッドがあるとして、メソッドを独自のオブジェクトに変え、全てのローカル変数がそのオブジェクトのインスタンス変数になるようにする。こうすれば、メソッドを分解して、同じオブジェクトの別のメソッドにすることが可能になる。

利点

  • ローカル変数はメソッドオブジェクトの属性になり、このオブジェクトを対象として「メソッドの抽出」を行うと、元のメソッド分解して小さなメソッドを作ることが可能になる。
  • 作成したオブジェクトのメソッドに処理を委譲することで、引数渡しの心配をせずにメソッドの抽出が可能になる。

ループからコレクションクロージャメソッド

ループではなく、コレクションクロージャメソッドを使う。

利点

  • コレクションの中を行き来したり、派生コレクションを作ったりするためのインフラストラクチャコードを隠し、ビジネスロジックに集中できるようにしてくれる。

Tips

managerOfiices = employees.select {|e| e.manager? }.
                            collect{|e| e.office }
  • 合計の計算のように、ループ内で一つの値を生み出すような処理をしなくてはいけない時には、
    injectメソッドを使用する。
total = employees.inject(0) {|sum, e| sum + e.salary}

サンドイッチメソッドの抽出

重複部分を抽出して、ブロック付きのメソッドにする。この種のメソッドは呼び出し元に一時的に制御を返してくる。呼び出し元は、制御を返された時に実行するコードをブロック内に記述する。

利点

  • 前後の重複部分を抽出してメソッドにまとめることができる。
  • インフラストラクチャコード(コネクションを反復処理するためのコード)を隠して、ビジネスロジックを全面に押し出すことができる。
    • つまり、公開メソッド内に保つことができるのでメンテナンスがしやすくなる。

クラスアノテーションの導入

クラス定義からクラスメソッドを呼び出してふるまいを宣言する。

利点

  • 宣言的な構文でコードの目的が明確につかめる場合には、「クラスアノテーションの導入」を使うと、コードの意図を明確にできる。
  • 有名な例としては、属性アクセッサが挙げられる。

Tips

  • 様々なクラスで使いまわせそうであれば、Moduleとして抽出して、Classクラスに移した方が良い。

名前付き引数の導入

引数リストをハッシュに変換し、ハッシュキーを引数の名前として使う。

利点

  • 他のオブジェクトに処理を移譲をしようする際に、渡す引数の役割が明確になっていれば(公開インターフェースが明確な振る舞いをきちんと表現していれば)、移譲先のオブジェクトの詳細を深く見なくても済む。

Tips

  • アサーションの導入すると、下記2点の利点がある。
    • 渡さなければいけない引数の種類の明確化
    • キーの綴りの間違い時の検出
module AssertValidKeys
    def assert_valid_keys(*valid_keys)
        unknown_keys = keys - [valid_keys].flatten
        if unknown_keys.any?
            raise(ArgumentError, "Unknown key(s): #{unknown_keys.join(",")}")
        end
    end

Hash.send(:include, AssertValidKeys) # Hashオブジェクトを拡張する。

Class Books
    def self.find(selector, hash={})

        # ここでhashに渡すキーの種類が確認できる。
        # 誤ったキーが与えられるとArgument Error が発生する。
        hash.assert_valid_keys :conditions, :joins

# 以下、省略
Books.find(:all)
Books.find(:first, :conditions => "authors.name = 'Jerry James'", :joins => [:authors])
  • 呼び出し元のコードが分かりやすくなるという利点がある一方で、呼び出されるメソッドが複雑になるコストもかかってしまうので、呼び出されるメソッドをそこまで複雑にする必要性がない場合は、名前付き引数を取り除く
    • 引数の数が減ったり、オプション引数の一部が必須引数になったりして、Hashの名前付き引数から、必須引数を取り除いた場合
    • メソッドの抽出」や「クラスの抽出」を行って、元の引数から一つだけ呼び出して引数とするようなメソッドやクラスを作った場合

動的メソッド定義

メソッドを動的に定義する。

利点

  • 読みやすくメンテナンスし易い形式でメソッド定義を簡潔に表現できる。

Tips

  • 単純なメソッドの繰り返しであれば下記のようなメソッドを定義しておくと便利である。
class Class
    def def_each(*method_names, $block)
        method_names.each do |method_name|
            define_method method_name do
                instance_exec method_name, &block
            end
        end
    end
end
def_each :failure, :error do |method_name|
    self.state = mathod_name
end
class Post
    def self.states(*args)
        args.each do |arg|
            define_method arg do
                self.state = arg
            end
        end
    end

    states :failure, :error, :success
end
  • 動的に定義されたモジュールをextendしてメソッドを定義する。
class to_module
    def to_module
        hash = self
        Module.new.do
            hash.each_pair do |key, value|
                define_method key do
                    value
                end
            end
        end
    end
end
class PostData
    def initialize(post_data)
        self.extend post_data.to_module
    end
end

動的レセプタから動的メソッド定義へ

動的メソッドを利用して必要なメソッドを定義する。

利点

  • method_missingを利用したクラスのデバッグは悲惨になりやすく、最悪の場合スタックレベルが深くなりすぎてエラーになる。オブジェクトがどのように使われているかわかっているケースではmethod_missingを使わずに振る舞いを実現できる。

Tips

  • method_missingを使わない動的な移譲
    • 無効なメソッド呼び出しはデコレータのNoMethodErrorsとして正しく報告される。
    • method_missing定義もないため、スタックレベルが深くなりすぎることもない。
class Decorator
    def initialize(subject)
        subject.public_methods(false).each do |meth|
            (class << self; self; end).class_eval do
                define_method meth do |*args|
                    subject.send meth, *args
                end
            end
        end
    end
end

属性の中にnilのものがあるかどうかを判定する。

class Person
    def self.attrs_with_empty_predicate(*args)
        attr_accessor *args

        args.each do |attribute|
            define_method "empty_#{attribute}?" do
                self.send(attribute).nil?
            end
        end
    end

    attrs_with_empty_predicate :name, :age
end

動的レセプタの分離

新しいクラスを導入し、method_missingのロジックをそのクラスに移す。

利点

  • 新しいクラスにメソッドmethod_missingを移動させることによって、method_missingを利用することで発生するデメリット(予想外のNoMethodErrorの頻発やSystemStackErrorを発生)を抑えることができる。

Tips

  • 有効なメソッド呼び出しは予めわかっていることが非常に多い。その場合は「動的レセプタから動的メソッド定義へ」を使ったほうが良い。