表参道.rb #31 で LINE でお天気bot をつくった話をしてきた
LT してきました。
今回もご飯がとても美味しすぎた…。
LINE でお天気bot をつくった話
https://osyo-manga.github.io/slide-omotesandorb-31-otenki-bot/index.html#/
と、いうことで今回は珍しく生産性のある話をしてきました。
年末に LINE でお天気 bot を作ったので、それで利用した API や Ruboty の紹介なんかをしてきました。
Ruboty のプラグインとして LINE のアダプタとお天気 bot のハンドラをつくったので API キーさえ用意してもらえればすぐに使える(はず…。
何か問題があれば Issues まで教えてください。
そんな感じで今回で5回目のLTをしてきましたー。
運営の方々、発表を聞いてくださった皆様、ありがとうございました。
今回はちょっと参加人数が少なくていつもとは違う趣向でしたが、これぐらいの人数のほうがみんなで色々と意見をいいながら話せるのでこれはこれでよかったかな?と思いました。
みんなでワイワイいいながらコードを見るのは楽しいですね!
そろそろ話すのにも慣れていきたい。
Ruby で (a ==1 && a== 2 && a==3) の結果を真にする
と、いうのが JavaScript 界隈で流行っているので Ruby でもやってみた
==
メソッドを定義する
多分一番簡単なやり方。 比較演算子そのものの結果を変えます。
a = Object.new def a.== other true end p a == 1 && a == 2 && a == 3 # => true
a
メソッドを定義する
Ruby ではメソッド呼び出しの際に ()
を省略する事が出来るので a()
というメソッド呼び出しを a
とだけで呼び出すことが出来ます。
def a @a = (@a || 0) + 1 end p a == 1 && a == 2 && a == 3 # => true
こっちは Ruby らしいですね。
おまけ:==
ではなくて ===
を使う
主題からは外れますが Ruby では ===
演算子は特別な呼び出しなので ==
の変わりに ===
を使うといろいろな手段が使えます。
Proc#===
を使う
Proc#===
は Proc#call
と同じなのでブロックの中身をそのまま返します。
a = proc { true } # a.call 1 と同じ p a === 1 && a === 2 && a === 3 # => true
Method#===
を使う
Method#===
も Proc#===
と同様に #call
を呼び出します。
a = [1, 2, 3].method(:include?) # [1, 2, 3].include? 1 を呼び出しているのと同じ p a === 1 && a === 2 && a === 3 # => true
Range#===
を使う
Range#===
は Range#include?
を呼び出します。
a = (1..3) # (1..3).include? 1 を呼び出しているのと同じ p a === 1 && a === 2 && a === 3 # => true
Set#===
を使う
Range
と同様に Set#===
も Set#include?
を呼び出します。
require "set" a = Set[1, 2, 3] # Set[1, 2, 3].include? 1 を呼び出しているのと同じ p a === 1 && a === 2 && a === 3 # => true
Ruby たのしい
Ubuntu で Dropbox の同期が出来なかったときの対処方法
Ruby の Hash のキーを Symbol に変更する
Ruby の Hash のキーを Symbol に変更したい場合、Ruby 2.5 で追加された Hash#transform_keys
を使うとよさそう。
hash = { "name" => "homu", "age" => 14 }.transform_keys(&:to_sym) # => {:name=>"homu", :age=>14}
こういうのをやりたいことは稀によくあるのでメソッド1つで出来るのはよさそう。
ただ、#transform_keys
って名前がちょっと長いので transform_keys(&:to_sym)
を呼び出すヘルパメソッドが欲しくなる。
ちなみに Hash#transform_keys!
だと自身を破壊的に変更します。
Toyama.rb に参加してきた
タイミングよくちょっと近くへ行く用事があったの Toyama.rb に参加してきました。
勉強会の内容はみんなで雑談しながらもくもくして最後にやったことを各自で発表するような会です。
やったこと
- Ruby 2.5 の導入
- Ruby 本体をビルド
- ファイルローカルなトップレベルメソッドを定義する gem の作成
- もの自体は30分ぐらいでできたんですがちょっと問題があったので修正してから公開する予定
どんな場面で必要なのか?
成果発表の時に「どういう場面で必要なのか?」と質問されたので補足
わたし自身は以下のような場面で使いたいと思うことが多いですかね。
- 長いメソッドから処理を切り出したい時
- DRY を行う際に重複している処理を別メソッド定義したい時
まあこの辺りは Ruby に限らずどの言語でも言えるかと思います。
private メソッドやモジュール関数ではダメ?
private メソッドもダメではないんですが、Ruby の private は簡単に外部から呼び出すことができるので完全に隠蔽できないという問題があります(そもそも Ruby の private はそういう目的の機能ではないというのは置いておいて。
また、個人的には DRY を行うという目的でそのクラスに「余計なメソッド」を定義したくないというのもありますね。
モジュール関数も同様に「トップレベルで定数(モジュール)を定義すること」になってしまうので隠蔽化が不完全であったり、そのファイル以外でも影響してしまうという問題があるのでそれを避けたいです。
以上の理由から「ファイルローカルメソッドを定義する」専用の機構がほしいなーという感じです。
あと口頭で解答していた時は「Rails みたいなフレームワークではなくてライブラリとか小さい範囲のプロジェクトで使うことが多いかなー」みたいな話もあったと思うんですが、これ自体は別に大小は関係ないと思います(Rails でも上記で挙げたようなケースでは利用することはあると思いすし…多分…。
参加してみて
と、いうことで Toyama.rb に参加してきましたー。
都内だと地域.rb は結構頻繁に行われていますが、こういう地方の Ruby の勉強会は少ないので貴重ですね。
みんなでワイワイ言いながら作業していたので割といい刺激になりました。
いい意味で人数も多くなく(物理的な意味でも)他の参加者と距離が近くて話しやすかったです。
そういう意味では何かコードとかをスクリーンに映して、それを見ながらみんなで意見を言い合ったりして議論をしてみるのもいいんじゃないかなーと思いました。
Ruby の勉強会と言いつつ内容は Ruby に限らない(実際参加した今回も Ruby 以外の作業を行っている人は何人かいました)ので近くに住んでいてきになる方は参加してみるとよいのではないでしょうか。
さすがに毎回参加することは難しいですが、機会があればまた参加してみたいと思います。
運営の方々ありがとうございましたー。
あと、これは今回の勉強会に限ったことはないんですが、もくもく会でみんな作業しているとなかなかわからないことなんかを相談するのが難しいので「つらいときにあげる札」なんかがほしいなーと思いましたまる。
そしてもうちょっとしゃべりが上手くなりたい…
C++ で each_split
C++ で split というと『戻り値型とかどうするの』みたいな問題があるんですが、『それなら戻り値ではなくて each みたいに関数オブジェクトを渡せばいいじゃん』みたいな感じでやってみた。
#include <iostream> #include <sstream> #include <string> auto each_split = [](auto src, char del, auto f){ std::stringstream input(src); std::string output; while(std::getline(input, output, del)){ f(output); } }; int main(){ each_split("homu,mami,mado", ',', [](auto str){ std::cout << str << std::endl; }); return 0; } /* output: homu mami mado */
関数テンプレートを定義するのがめんどくさかったのでラムダ式を使っていますが、実装には関係ないです。
rbenv をインストールしたので覚書
今まで めんどくさかったので rbenv を使っていなかったのですが Ruby 2.5 をインストールする為に入れたのでその覚書。
rbenv とは?みたいなことは以下の記事を参照してください。
事前準備
すでに system の gem で bundle などをインストールしている場合は削除しておくと混乱が少ない。
$ gem uninstall bundler $ gem uninstall bundle
あと ~/.bundle
なども削除しておく。
rbenv のダウンロード
rbenv 本体は ~/.rbenv
に保存
$ git clone git://github.com/sstephenson/rbenv.git ~/.rbenv
ruby-build のダウンロード
rbenv 以外に Ruby 本体をインストールするための ruby-build が必要なのでそれの保存。
$ mkdir -p ~/.rbenv/plugins $ cd ~/.rbenv/plugins $ git clone git://github.com/sstephenson/ruby-build.git
.bashrc
に rbenv を読み込む設定を追記
rbenv をダウンロードしただけでは PATH
などが設定されていないので .bashrc
で設定を初期化するように追記。
export RBENV_ROOT="${HOME}/.rbenv" if [ -d "${RBENV_ROOT}" ]; then export PATH="${RBENV_ROOT}/bin:${PATH}" eval "$(rbenv init -)" fi
Ruby のインストール
rbenv install
で Ruby のインストールし、rbenv global
で使用する Ruby を設定する。
$ rbenv install 2.5.0 # rbenv intall や gem install した後に呼び出す $ rbenv rehash # global で使用する Ruby の設定 $ rbevn global 2.5.0 $ ruby -v ruby 2.5.0p0 (2017-12-25 revision 61468) [x86_64-linux]
rbevn rehash
を忘れないように。
ruby -v
で system の Ruby を参照してる場合に試すこと
rbenv versions
の確認
rbenv versions
で現在インストールしてる Ruby と設定されている Ruby を確認する。
$ rbenv versions system * 2.5.0 (set by /home/worker/.rbenv/version)
rbenv local
をリセット
可能性は低いんですが rbenv local --unset
でローカルのバージョンを削除してみる。
$ rbenv local --unset $ rbenv rehash
bundle install
でハマった
bundle install
した際に rbenv ではなくて system 側の gem を参照しておりはまった。
bundle
の PATH を確認
bundle
コマンドが rbenv 側のものを参照しているか確認
$ which bundle ~/.rbenv/shims/bundle
~/.bundle
を削除
手元だとこれを削除したら改善しました。