ここまで出来る!RubyのSplat Operatorまとめ

Splat Operatorとは、*のことです

SplatOperator

この前、友人にコードレビューしてもらっていたら

「え、Rubyってこんな書き方出来るんですか?」と言われて、「知らない人もいるんだなぁ」と思ったので簡単なまとめ

Splat Operatorの色んな使い方

Splat Operatorは、応用の幅が広いです。

結構当たり前だと思っていましたが、コード読書しないと見る機会は少ないかも。

1-1. 配列に変換する

まずは基本編。配列に変換してやりましょう

文字列やsymbolは.to_aが無いですが、*を使えばどの変数でも配列に出来ちゃいます。

string = *"string"
p string #=> ["string"]

symbol = *:symbol
p symbol #=> [:symbol]

hash = *{ hash: nil }
p hash #=> [[:hash, nil]]

range = *(1..10)
p range #=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

1-2. 親クラスの引数を気にしない

またまた基本編。*を引数に指定してやれば、親クラスの引数は知らなくても大丈夫。

*だけで出来ることを知らない人はいるかも。

class Child < Super
  def initialize(*)
    super
  end
end

1-3. 間の引数をまとめる

引数の最後にSplat Operatorを使うことはよくありますが、間はなかなか見ないですね。

blockで引数を取るときに、間の引数をまとめる事が出来ます。

メソッドやProc,lambdaでも同様の動作です。

list = [[:first, :second, :third, :fourth, :fifth]]
list.each do |first, *mid, last|
  p first  #=> :first
  p mid    #=> [:second, :third, :fourth]
  p last   #=> :fifth
end

# もちろん、こんなことも出来ます
first, *other = [1, 2, 3]
p other #=> [2, 3]

1-4. **を使う

キーワード引数って、まだあまり普及してないですね。互換性が気になるからだろうか?

**はキーワード引数を取るときに、余った引数をまとめます。

def hoge(first: 1, second: 2, **others)
  p others #=> { third: 3 }
end
hoge(first: 1, second: 2, third: 3)

多分これはSplat Operatorと呼ばない。

まとめ

こんな書き方が出来るSplat Operatorって本当に便利ね!

( ゚∀゚)o彡゚んぎもぢいい!!

class Integer
  def upto_with_exception(to, **options)
    exception_array = *options[:except] #=> nilでも何でもおかまいなし!
    exceptions = Hash[exception_array.zip]

    self.upto(to) { |i| p i unless exceptions.has_key?(i) }
  end
end

1.upto_with_exception(5) #=> 1, 2, 3, 4, 5
1.upto_with_exception(5, except: 3) #=> 1, 2, 4, 5
1.upto_with_exception(5, except: 2..3) #=> 1, 4, 5
1.upto_with_exception(5, except: [4, 5]) #=> 1, 2, 3

久しぶりにGemを書いている

最近、久しぶりにGemを書いてます。

去年からwatson-rubyというinline issue manager貢献してます。

watsonは凄い便利なんですが、コードがかなりアレなのです…。

「全部リファクタリングさせてくれー!」って言っても、まだやりたい作業があるらしく「ブランチ切るから、もう少し待ってて:)」と言われたっきり…

うーむ、、なかなか全部は触れないので、とりあえず一番やっかいな部分だけ汎用的にすべく自作しました。

どんなGem?

あらゆるプログラムソースを読み取って、コメント行のみを取り出すGemです。watsonでは、このコメント行を読み取って、todoの管理を行っています。

最近のwatsonのPRを見ても、対応ファイルの追加(正規表現の追記)ばかりなのです。こんなもの、他のGemにくれてしまえ!

どんなファイルタイプであれ、扱うのはコメントという概念なのだから、委譲して抽象化しちゃいましょう。

何が出来るようになるんだい?

あらゆるプログラムのソースコードをパースして、コメント行だけを抽象的に扱う事が出来ます。

読み取って、何らかの処理をすることが出来ます。

# 今のところはこんな感じ。
# Gem名やmethod名は変更します
require 'strip_comment'

path = '/path/to/file'
file = StripComment::FileObject.new(path)
parser = StripComment::Parser.for(file)
parser.scan
parser.comments # => [StripComment::CodeObject::Comment, ...]

簡単に思いつく限りの用途はこんな感じ。

  • 英語のコメントの文法チェック / 翻訳
  • [review - @alpaca-tc ここ見ておいて!]というコメントにGit post-hookをかけて、ダイレクトメッセージを送る
  • iftttとの連携

他にも色々出来そうですね。

Vimでテスト

さっそくVimと連携してみました。

comment.vimデモ

コメント行を取り出して、Gingerで文法チェックしています。

まとめ

あとは対応ファイルを増やして、リファクタリングしたら完成です。 今StripCommentという名前なんだけど、絶対違うよね。(´・ω・`)良い名前が思いつかない

終わったら誰か、コードレビューして欲しいなぁ!ヽ(・∀・ )ノわーい

逆就活へ参加するときのノウハウまとめ 続き

再び逆就活に参加してきました!

逆就活へ初めて参加される方は、前の記事から見ると良いと思います。-> 逆就活へ参加するときのノウハウまとめ

1/18(土)に参加したITエンジニア逆求人についての報告です:)

逆就活へリベンジ

前回の失敗を活かして、「イベントに参加するメリットを最大化する」ための解決策を実践して来ました。

ということで、次回参加する際には3社ぐらいからしか面談希望が来ないぐらいになれば合格かなぁ、と思います。

こんなことを言っていたのですが、結果は如何に。

試したことと、その結果

捨てること、そして集中すること。

双方のために、不要なものは捨てて、重要なことに集中することが大事かと。

相手の時間を無駄にすることも、自分の時間を無駄にすることも悪だと思います。

さて、前回と今回の結果を比べるため、Gvalueという数値を挙げます。これは、イベント後に企業から送られてくる評価シートで、面談した企業からの評価が全て分かります。

G-valueの比較

1. 名刺交換の段階で、合わない企業さんは断る

当日に会わない企業を決める

逆就活では、当日のイベントの前に企業の一覧が送られてきます。今回は、28社が登録されていました。

まず、その一覧をターゲット, 中ターゲット(判断出来ない), 捨てるターゲットに選びました。

僕は次の順番で優先順位を決めました。

  1. 捨てるターゲット(合わない企業)を消す
  2. ターゲット(合うと思う企業)をリストアップする
  3. 残った企業について、中 or 捨てるターゲットに振り分ける

残りを振り分ける方法としては、有価証券報告書、取締役の人の書いた本、転職会議の情報を横断的に見て、自分と合うか考えると良いと思います。

最終的に、ターゲットを3社に絞ります。今回は、捨てるターゲットに選んだ企業さんは名刺交換会の段階で断りました。

結果

  • 志向の近い企業が面談に集まった
  • 捨てるターゲットに選んでいた企業は1社のみ面談
  • 重要な成果をあげる時間(ターゲット企業との面談)に集中できた

2. 名刺交換の際に、MBAで録画する

入れ替わり立ち代わりで、10~20人を覚えるのは無理です。笑 なので、MacBookAirで録画しながら名刺交換をします。

と言っていましたが、身長差激しくて録画無理www 今回は長身の方が多かったです…。

よく考えたら、名刺交換しているのにMBAを見ないですしね。何か無意識に目が行くような画像を表示させておくと、良いと思います!

3. プロフィールはターゲットに向けて作る

続いて、ターゲット各社の採用情報サイトを読んで、求める人材像の共通解を出しました。

  • 主体性を持っている
  • 挑戦者である
  • チームワークを重んじる
  • 問題解決が楽しい

まぁ…大体どこも同じようなこと書いてあるんです。これらは、元々自分が持っている特性だったので、プロフィールはあまり変更しませんでした。

ただ、採用情報以外にも共通項(志望動機)があると思うので、同時に挙げておくと良いですね。

3. 面談は重要なことに集中する

前回の反省であげたフローは次の通りです。

  1. 面談開始のときに、面談の目的をお互いに確認する
  2. その企業が求めている人材を確認する。(プロフィールのどこを見て来たのか、何位に指名したのか)
  3. 自分が出来ることと、企業に入ってやりたいことをプレゼンする
  4. 企業と雑談する

実際に実践しました!予想通り、1.面談開始のときに、面談の目的をお互いに確認するの段階で目的に齟齬がある企業さんもいました。「なぜ、僕を指名されたのでしょうか…?」となって、噛み合なかったです。;(

でも、多くの企業さんとは面談開始の時点で、互いの目的を確認し合える面談になったと思います。

結果

  • ターゲットの会社からのGvalueが全て満点(!!)
  • ターゲット以外の企業からの「面接態度」のGvalueが悪くなった
  • 捨てるターゲットを除いたプレゼンのGvalueが、3.67(前回) -> 4.8

あと、捨てるターゲットに選んでいた企業とのマッチ度が最低だったので、この方法は合っていると確信しました。

まとめ

「捨てて良かったー!」の一言に尽きますね。ばっちり成果を出せたと思います。

自分と合う企業との面談のためだけに全てを集中したので、前回よりエッジの効いた思考になれたと思います。きっと、就活ってこういったマッチングをするものなのかなと思いました。

そして、疲れないということに驚き。もちろん、肉体疲労はありますが、前回の倍のターム数をこなしたにも関わらず精神疲労はありませんでした。

引き続き、選考を楽しみたいと思いますー。

おまけ1: 資料

もうきっとIT逆求人に参加しなさそうなので、公開しても問題無い…よね?今の選考が全て落ちるか、留年したら再度応募しますが:p

おまけ2: Gstylusさんへ

お世話になりました!僕のようなはみ出しものには、救いのあるイベントでしたw いつも僕たちのために夜遅くまでお仕事してくださっているおかげで、実のある体験が出来ました。

お話は変わりますが、システム・Webサービス周りでお困りでは無いですか? 夜遅くまでお仕事されていますし、多少であれば自動化のお手伝い出来るかもしれません!

2週間程度で実装できる機能がありましたら、お手伝いしますので連絡くださいー:)

2014年にやりたい14のこと

Takumi Kaiさんの2014年にやりたい27のことを読んで、こういうのを記事にするのも良いなぁと思った。

思考は現実になる

この言葉は僕も好きだし、新しくやることを考えるのは楽しいんだよ!

今年やることのリストを考えてみた:)

一人でやることリスト

1. 海外に行く

海外の美術館に凄い興味あります

2. 美術館に行く

今年は特に、予約が必要な個人のアトリエとか行きたいなー!

3. 東京まで散歩する

散歩が趣味です

東京まで7日かからないみたいなので、就活がてら歩くよー:)

200 東京から滋賀まで歩く

4. 岡本太郎の本を3冊読む(完)

中学生のころからたまらなく好き。

20代の決意を新たにするために、読まないといけない!

岡本太郎の本

5. 今年も1,000時間以上プログラミングする

今のところの累計は8,500時間ぐらい。就活早く終われー

7. Vim Version3を読み切る

別の言語でVimを再実装する試み。もっとVimを愛さなければ…。

人とやる事

7. アルパカのはんこを掘る

祖父がはんこ職人で、僕も家に帰ったら彫刻刀で掘ってます。

文字しか掘らないけれど、せっかくだしイラストのハンコ掘ってみたいなァ

 200 判子を掘る

8. 前職でお世話になった人に会う(完)

ドリラボ時代の先輩方に会いたい!

尊敬している杉さんには昨晩会えました(゚∀゚)

9. 酒蔵に行く

東京で、酒蔵で働いているまっちゃんという方に日本酒の話を聞いて、感動しました。

「この方ぐらい勉強しないと日本酒に失礼だ。」

と思ったので、日本酒好きな同年代集めて酒蔵に行くよ。

10. 金沢の芸術家の一家に会いにいく

昨年、金沢の喫茶店で美味しいコーヒーを飲んでいたら、色々あって芸術家の家に泊まることになった。

あれは、人生でトップクラスに楽しい一日だった。

一宿一飯の恩があるので、今年中にお礼に行きたい!

仕事とかやりたいこと

長々と書いてきたので、少しはしょります。

  • 11.自分のブログ500uu/day アクセス
  • 12.自分のポートフォリオサイトを作る(完)
  • 13.仕事の事業を軌道に乗せる
  • 14.意思決定・事業計画の知識を学ぶ

人生について考える

2014年にやること・やりたいことを考えるのは楽しいなぁー。

こうやって考えていて思ったけれど、仕事を始めてから「大学で何かしたい」という考えがさっぱり無くなった。

関西学生エンジニアの猛者たちは、思いっきりが良くて凄い。自分は、常識を捨てられないのか、度胸が無いのか、あるいは大学を卒業するのが正しいのか。。

本当は、大学なんてすぐにやめて、またしっかり働きたいよ。

neocomplete.vimのfile_includeを使いこなす

この記事はVim Advent Calendar 2013の42日目の記事になります。

Neocomplete.vimのfile_includeを使いこなす

さて、今回の記事ではneocompleteのfile_includeを使いこなしてみます。

neocomplete_file_include

file_includeとは、ファイルパスを補完してくれるアレです。file補完との違いは、特定のキーワードや変換を含んだ補完が出来る点です。

  1. キーワード(require#include)があると補完が始まり
  2. 指定されたパスの中から候補を探し、変換して表示します。(例:system.os)

内部では、path, include, includeexprなどが使われています。(pathの参考 -> Vim中級者を脱する Path編)

neocompleteを拡張する

file_includeを拡張する際には、neocompleteの設定をしてあげる必要があります。それぞれ、次のように5つ変数をファイルタイプ毎に設定します。

指定しなければ、デフォルトの部分の変数が使用されます

" Liquidで画像pathを補完する

" デフォルト &l:path(検索対象のディレクトリ`,`区切り)
let g:neocomplete#sources#include#paths.liquid =
  \ '/Users/alpaca-tc/projects/alpaca-tc.github.io/source'

" デフォルト &l:include(正規表現にマッチしたら補完を開始)
let g:neocomplete#sources#include#patterns.liquid =
  \ '\({\s*%\(\s\+\w\+\)\+\(\s*\|\s\+[a-zA-Z0-9_#\?\!]\+\)\@=\|{\s*{\(\s\+\w\+\)\+\(\s*\|\s\+[a-zA-Z0-9_#\?\!]\+\)\@=\)'

" デフォルト &l:includeexpr(ファイルパスを出力する際に変換する)
let g:neocomplete#sources#include#exprs.liquid =
  \ 'substitute(v:fname, "^/", "", "")'

" デフォルト '.'(区切り文字の指定)
let g:neocomplete#sources#file_include#delimiters.liquid = '/'

" デフォルト [](補完するファイル拡張子フィルター)
let g:neocomplete#sources#file_include#exts.liquid =
  \ ['png', 'jpg', 'gif', 'jpeg', 'ico']

解説いる?

先ほどのコードを読めば、だいたい分かると思います。(あなたがVimmerなら!)

もし、マイナーな言語でfile_include補完があった方が便利ならば、拡張してみてくださいー。

あるいは、&l:include, &l:includeexprなどで対応出来ているかもしれませんが。neocomplete.vim自体に設定が少ないのはそういうことです、(よね…?)

個人的には、フレームワーク毎にfile_includeが使いたい所存です。

Railsのimage_pathを補完してみる

最後です。

Railsでimage_pathを入力する際に、typoが多いので補完で対応してみます。

こんな感じで色々対応出来るはずなので、誰か本格的なRails用カスタマイズを作ってみてくれたらうれしいです!

" Rails.vimが必須
function! s:setup_include_file_for_rails()
  if !exists('b:rails_root') || !exists('g:neocomplete#sources#include#paths')
    return
  endif

  let g:neocomplete#sources#include#patterns.haml =
        \ '^\s*\<\%(image_path\|image_tag\)\>'
  let g:neocomplete#sources#include#paths.haml =
        \ b:rails_root . '/app/assets/images'
  let g:neocomplete#sources#include#exprs.haml =
        \ "substitute(substitute(v:fname,'::','/','g'),'$','','')"
  let g:neocomplete#sources#file_include#exts.haml =
        \ ['png', 'jpg', 'gif', 'jpeg', 'ico']
  let g:neocomplete#sources#file_include#delimiters.haml = '/'
endfunction
command! RailsView call s:setup_include_file_for_rails()

うっほい!

completion_for_rails_view

Shougoさんいつもありがとうございます。本当に。

ちなみに、tpopeさんはこんな感じの事を剛腕で捩じ伏せて実現しています。Vimガチ勢怖い…。

Vim Advent Calendar 45

前日は@osyo_mangaさんのtextobj の両端へ移動する operator つくったでした。

は!またosyoさんということは…!? と思っていたら、やはりVim Advent Calendarの今後の投稿者が居ませんでした;(

このブログを見ているあなた!(特にここまで読み切ったVim狂)

どうせVimmerしか居ない事は分かっています。ぜひ書いてください -> osyoさんに「記事書きたいですー」とリプライ飛ばしましょうー!