第8回 学生エンジニア限定LT大会!!! でエモい話をしてきた

前回に懲りずに学生に混ざってLTしてきました。

9年間ブログを書き続けて得たもの

https://osyo-manga.github.io/slide-gakusei_LT-08-9years-blog/#/

内容は『アウトプットすることで自分にもプラスになるんやで』みたいな事を話してきました。
まあ、アウトプットすることは大事なんですけど、自分にも役に立つのでいいですよねー。
皆さん、どんどんアウトプットしていきましょう。

本日のハイライト

懇親会で LT をしているあいだにピザと寿司が全部食べれられてしまっていた。
ゆるさん。
今度参加したときは2倍食べてやる!!!

表参道.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 の同期が出来なかったときの対処方法

最近 Ubuntu を入れ直したんですが、その時に Dropbox の同期がうまくいかなかったので覚書。
Linux 版の Dropbox アプリの場合、デフォルトの設定では『1 万件以上のフォルダを監視すること』が出来ないため、以下のようなコマンドを端末から実行して回避する必要がある。

# 10 万件までのフォルダを監視するように指示する
$ echo fs.inotify.max_user_watches=100000 | sudo tee -a /etc/sysctl.conf; sudo sysctl -p

参照

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
*/

関数テンプレートを定義するのがめんどくさかったのでラムダ式を使っていますが、実装には関係ないです。