下級エンジニアの綴

新しく発見したことを綴っていこうと思っています。夢はでっかく上級エンジニアになることです。

go初心者が無名関数のクロージャについて学んだのでメモ

スターティングGo言語という本を読んでいるのですが、これは面白そうだなと思った機能があったのでメモ

package main
import "fmt"
func later() func(string) string { 
    // 1 つ 前 に 与え られ た 文字列 を 保存 する ため の 変数 
    var store string 
    // 引数 に 文字列 を とり 文字列 を 返す 関数 を 返す 
    return func( next string) string { 
        s := store store = next 
        return s 
    } 
} 
func main() {
    f := later() 
    fmt.Println(f("Golang")) // => "" 
    fmt.Println(f("is")) // => "Golang" 
    fmt.Println(f("awesome!")) // => "is"
}
a := 1
b := 2 // この変数だけクロージャから参照される
c := 3
return func() int{
    return b
}
package main

import "fmt"

func integers() func() int { 
    i := 0
    return func() int { 
        i += 1 
        return i 
    } 
} 

func main() { 
    ints := integers() 

    fmt.Println(ints()) // => "1" 
    fmt.Println(ints()) // => "2" 
    fmt.Println(ints()) // => "3" 

    otherInts := integers() 
    fmt.Println(otherInts()) // => "1" 

    fmt.Println(ints()) // => "4" 
    fmt.Println(ints()) // => "5" 

  // 初期化
    ints = integers() 

    fmt.Println(ints()) // => "1" 
    fmt.Println(ints()) // => "2" 
}

上手く使いこなせれると便利そうだなと思いました。

スターティングGo言語

スターティングGo言語

builderscon2017に行って来ました

buildersconとは

buildersconは「知らなかった、を聞く」をテーマとした技術を愛する全てのギーク達のお祭りです。buildersconではトークに関して技術的な制約はありません、特定のプログラミング言語や技術スタックによるくくりも設けません。 必要なのは技術者達に刺激を与えワクワクさせてくれるアイデアのみです。

あなたが実装したクレイジーなハックを見せて下さい。あなたの好きな言語のディープな知識をシェアしてください。あなたの直面した様々な問題と、それをどう解決したかを教えてください。未来技術のような未知の領域について教えてください。

buildersconに参加して、あなたの情熱をシェアしてください!皆様のご参加をお待ちしております!(下記より引用

builderscon.io f:id:yanterakun:20170806182044j:plain

2017/08/03〜2017/08/05で開催されていたので行った感想をまとめたいと思います。
(私が参加したのは4・5日なのでその感想になります。

4日

初めてのMySQLチューニング -データベースは怖くない!

builderscon.io

mysql5.5のチューニングをされたというお話でした。
my.cnfがデフォルトだったり、slaveがない状態で運用を引き継いだ時に学んだ教訓や対応方法を発表されていました。
自分も5.5, 5.6でslaveの作成やmaster昇格などを勉強しましたが、5.6からgtidがあるのでそこまで大変ではないのですが、5.5だとdbをロックしてdumpしてpositionを見てと結構な手数があるので改めてgtidを使える5.6はありがたいと思いました。
他にも、「運用から逃げるのは良くない」など自分にもかなり刺さり、印象深いお話でした。

ランチセッション

ここでは株式会社VOYAGE GROUPとMomentum株式会社の方々の話を聞きながらランチを食べました。
ランチに頂いたお弁当がめっちゃおいしかったです。(写真を撮るのを忘れていましたorz

横山三国志に「うむ」は何コマある?〜マンガ全文検索システムの構築

builderscon.io

趣味で全文検索をされているというお話でしたが、かなり正確な検索をされていたのでとても凄かったです。 最初は横山光輝三国志だけだったそうですが、コナンやドラゴンボールなど漫画のコマが一定の作品以外の作品でも検索できるようになっていました。 思わず自分もクソリプを送るためのコマ面白いコマを抜き出したいなと思いました。 トークもかなり軽快だったのですごく楽しかったです。 ベストトーク賞2位おめでとうございます

Goで実装する軽量マークアップ言語パーサー

builderscon.io

speakerdeck.com

はてな記法のパーサーをgoで実装されたというお話でした。どの言語にも対応できるようにと設計もされていたので凄いなと思いました。

RDBアンチパターン リファクタリング

builderscon.io speakerdeck.com

技術的負債がチーズなのか腐った牛乳なのかと発表されていてなるほど!上手い例えだなと思いました。
負債が自分たちの飯の種になっているというのもあるので、そこから逃げ出さずに返済しましょうというお話でした。
これには自分もかなり納得で且つ耳が痛いお話だなと思いました。
RDBということなので、データベースでのお話でしたが、データだけではなく、アプリケーションでも同じことが言えるので自分もそこから逃げず頑張ろうと思います。
ベストトーク賞1位おめでとうございます!

LT

基本的に皆さんトークを5分以内に終わらせるのすげーって思いました。
たくさんの人の前できっちり発表されていたので本当に上手で、時間を守るだけでなく内容も皆さん濃いので最後まで楽しかったです。
QRコードを16分割したやラズパイでGPSアプリ作ってみたや自分の作ったものを発表していく(デモ付き)等、全体的にめちゃくちゃ面白かったです。

5日

この日はちょっと遅刻しました(5分ほど
見たいセッションは観れたので個人的にはセーフです。

ここまで出来るmruby

builderscon.io

speakerdeck.com

実際にサービスでの実体験を元に発表されていました。なのでかなり勉強になりました。 そしてruby凄いって思いました。mrubyを使うと低レイヤー部分も処理をかけるようになるので、rubyistである自分は触ってみようと思いました。

Ionic 3+ではじめる次世代アプリ開発(HTMLでiPhoneアプリをつくろう!)

builderscon.io

html5と少しのjsの知識があれば簡単にweb/ios/androidで使用できるということだったので、目からウロコでした。

ランチセッション

2日目のお弁当もかなり美味いお弁当だったので腹ペコの自分には至福の時でした。(コーヒーも頂いたのですが、このコーヒーもかなり美味しかったです。
サイボウズ株式会社とSupership株式会社の方たちのセッションを聞きながらいただきました。 f:id:yanterakun:20170806182750j:plain

OSS の引き継ぎ方

builderscon.io

speakerdeck.com

ossへの貢献の仕方っていっぱいあるんだなと思いました。(レビューやプラグインの開発、又は他人からその機能を引き継ぐなど
自分はまだそういったことがしたことがないので。これを機会に動いていきたいと思いました。
残念ながら時間切れということもあって最後まで内容を発表出来ていなかったのですが、続きはasakusa.rbに参加してお話を聞かせていただたいと思いました。

WEB+DB PRESS 100号記念 特別企画

builderscon.io

2部構成で進んでいきました。

1部:WEB+DBの過去を振り返る(1〜100
  • 1〜24巻までの6年間はjavaがメインだった
  • 25〜48でjavaからスクリプト言語に移行していった。
  • 49〜72モバイルからスマホに移行githubもこの期間にでた
  • 73〜99ではネイティブアプリや仮装技術、コンテナ技術が流行しだした
  • 100で人工知能

など技術のトレンドとともに振り返って楽しかったです。

2部:編集部に対しての質問
  • 編集部の技術のキャッチアップ方法

    • ライターから教えてもらう
  • ライターの探し方

    • 別のライターからの紹介
    • SNSからのキャッチする
  • WEB+DBとは

    • webアプリケーション開発に関連するものが中心に存在する
  • 応募方法

    • 編集部に直接メールを送る
    • ライターさんに紹介してもらう

などのWEB+DBに対しての質問時間でした。 WEB+DBについて色々知ることが出来てよかったです。

汎用CMSから新規開発の自社サービスへ移行した事例のご紹介

builderscon.io

実際の業務で行った事例を元に発表されていました。
自分も新旧のサービス移行が発生した場合のアンチパターンを踏み抜かないように気をつけようと思いました。

所感

参加して良かったなと思いました。
開発するモチベーションが上がったという事と、他社さんの事例を多くインプットさせて頂いたのでかなりモチベーションが高くなりました。
次回も参加出来たら良いなと思います。
登壇者さん、運営の皆さんありがとうございました。

re:dashユーザ追加でハマったのでメモ

re:dashをdockerで立てて運用した時に新規ユーザーを作成しようとしましたが、少し時間がかかったので手順をまとめました。

GUIで行う場合はメールサーバを立てないとメールが送られてこないので、ユーザーを作成しても仮パスワードが送られてきません。

なのでユーザを追加する時はメールサーバか直接ユーザ作成のコマンドを叩きましょう!

今回はメールサーバをを立てずにCLIで実行する時の手順をまとめました。

  • redashがあるフォルダに移動します
$ cd /opt/docker/redash/
  • re:dashはdockerで立てているのでプロセスを確認してください
$ docker ps
a460fb29f959        redash/nginx:latest    "nginx -g 'daemon off"   5 months ago        Up 5 months         0.0.0.0:80->80/tcp, 443/tcp        redash_redash-nginx_2
922aae8a262d        redash/redash:latest   "supervisord -c /opt/"   5 months ago        Up 5 months         0.0.0.0:6000->6000/tcp, 9002/tcp   redash_redash_2
2674c781bda9        postgres:9.3           "/docker-entrypoint.s"   5 months ago        Up 5 months         6543/tcp                           redash_postgres_2
c6e145400d1b        redis:2.8              "docker-entrypoint.sh"   5 months ago        Up 5 months         7379/tcp                           redash_redis_2
  • 次のコマンドを実行してください docker exec -it redash_redash_2 ./manage.py users create [name] [email]
  • 最終行でパスワードを入力できるので設定すると登録完了になります。
$ docker exec -it redash_redash_2 ./manage.py users create test test@gmail.com
[2017-07-06 12:18:44,544][PID:2891][INFO][requests.packages.urllib3.connectionpool] Starting new HTTP connection (1): metadata.google.internal
[2017-07-06 12:18:44,547][PID:2891][WARNING][redash.query_runner] BigQueryGCE query runner enabled but not supported, not registering. Either disable or install missing dependencies.
Creating user (test@gmail.com, test) in organization default...
Admin: False
Login with Google Auth: False

Password:

勉強になりました。

rubyのeachメソッドについて少し調べてみた

結論を先に述べるとよくわからなかったです。 とりあえず、調べた内容を残しておきました。

hoge = [{0=> 'aaaa'}, {1=> 'bbb'}, {2=> 'ccc'}]

hoge.each.with_index do |a, index|
  p a.object_id, hoge[index].object_id
end

p hoge
69822855751840
69822855751840
69822855751800
69822855751800
69822855751760
69822855751760
 [{0=>"aaaa"}, {1=>"bbb"}, {2=>"ccc"}] 

こう見ると、a.object_id, hoge[index].object_idは同じオブジェクトのように見える。

hoge.each.with_index do |a, index|
  a = {(index) => 'ddddddd'}
end

p hoge
 [{0=>"aaaa"}, {1=>"bbb"}, {2=>"ccc"}] 
hoge.each.with_index do |a, index|
  a[index] = 'ddddddd'
end

p hoge
[{0=>"ddddddd"}, {1=>"ddddddd"}, {2=>"ddddddd"}] 

↑2つの挙動は同じだと思うのだが、実際は違う・・・ 謎だ・・・

[{0=>{}}, {1=>{}}, {2=>{}}]  
hoge.each.with_index do |a, index|
  p a, index, hoge
  hoge.delete a
end

p hoge
{0=>{}}
0
[{0=>{}}, {1=>{}}, {2=>{}}]
{2=>{}}       
1         
[{1=>{}}, {2=>{}}]
[{1=>{}}]               

deleteメソッドを使うとこの用にレシーバを書き変えることが出来た。

rubyソースコードまでは読めていないので、本日はここまでにさせていただきます。

とりあえず、コメント書いとけば良いと思っているエンジニアを減らしたい

どうもやんてらです。

今回は技術的な記事ではなくて個人的に思っていることを書いていこうと思っています。 (内容は愚痴になりますので不愉快だと思われる方はブラウザバックをお願いします。)

今回取り上げた内容は「コメント」です。

ソースコードの中にコメントを書くという文化を否定したいわけではないのですが、メソッド名や変数名を特に考えずにコメントで補えば良いと思っているエンジニアに一言申し上げたくて記事にしました。

※サンプルのコードはrubyになります

def show_cost_per_click(ad)
   ad_value(ad)
end

# 有効なad判別したい
def ad_value(ad)
  ad.cpc if ad.present?
end

↑のソースを読んで思ったことが何個かありました。

先ずはじめに、adの値メソッドの「戻り値が何なのか?」というのと「このメソッドでやりたいことって何?」ということでした。 コメントには有効なadの判別をしたいと書いてありますが、「本当にこのメソッド名で良いのか?」って私は思いました。

コメントを残す前に適切なメソッド名をつけて欲しいなと個人的には思っているので、 この場合ですと、available_adみたいなメソッドであれば凄くわかりやすかったです。この場合であればコメントも別に書かなくても英語を翻訳するだけでやりたいことは伝わるかなと思います。

個人的な良い例

def show_cost_per_click(ad)
  ad.cpc if available_click?(ad)
end

def available_ad?(ad)
  ad.present?
end

↑のような状態で補足したい場合も、もちろんあると思います。その時にこそコメントを残してくれればありがたいと思います。 しかし、そういう場合以外でコメントで補おうとしてしまうと次に改修する人のコストになってしまうので避けて欲しいなと思います。

個人的には変数名やメソッド名に悩めば悩むほどスッキリとしたコードになることが多いので、もっと変数名とメソッド名に意味を持して欲しいなと思いました。

(コードを書き始めて日が浅い人やリーダブルコードを読んだことのない人は一度読んでみて頂きたいです。

長文でしたが、最期までお付合い頂きありがとうございました。

rubyのnilを0にしたいときに調べたのでメモ

数値を扱っているときにnilを使いたくないので、調べたらいい感じに行けそうだったのでメモ。

nil.nil?       # true
nil.to_i       # 0
nil.to_i.nil?  # false
nil.to_s       # ""
nil.to_s.nil?  # false
nil.to_s.empty # true

rubyって面白いですね。

Wunderlistに設定しているタスクを毎日(平日限定)slackに通知する流れを作ってみた

slackにタスクを毎日通知してくれるいい感じのツールが見つからなかったので、自作してみました。

必要なもの

手順

※wunderlistにタスクが登録されている前提で進めていきます

node.jsのインストール
yum install epel-release
yum install nodejs npm
yum install gcc gcc-c++
wunderlineのインストール
npm install -g wunderline
rubyのインストール

下記サイトを参考にしてください(手抜きで大変申し訳ないですmm)

CentOS に Ruby をインストールする - kzy52's blog

実際のコード
#!/usr/bin/env ruby
require 'slack'
require 'json'

### confの内容
※confは下記のように定義しています
######################################
slack_token,slack_token
wunderlist_token,wunderlist_token
client_id,client_id
channel,channel
wunder_list_url,wunder_list_url
######################################

- slack_token          # slackに通知するためのtoken
- wunderlist_token     # wunderlistに通知するためのtoken
- client_id            # wunderlistのclient_id
- channel               # 通知したいslackのチャンネル
- wunder_list_url      # wunderlistで叩きたいapiのURL


conf_file_path = '/home/[ユーザー名]/slack_bots/schedule_conf.txt' # cronを実行するユーザーがfile openするので絶対パスがおすすめ

### confの取得
datas = []
begin
  File.open(conf_file_path) do |file|
    file.each_line do |line|
      datas.push(line.chomp!)
    end
  end
end

### 取得したconfをhash化する
scheduler = {}
datas.each do |data|
  ary = data.split(',')
  scheduler[ary.first] = ary.last
end

### wunserlistからjson形式でパラメータを取得
result = `curl -H "X-Access-Token: #{scheduler["wunderlist_token"]}" -H "X-Client-ID: #{scheduler["client_id"]}" #{scheduler["wunderlist_url"]}`

result = JSON.parse(result)

### slackで表示するために整形
tasks = []
result.each do |r|
  tasks.push(r["title"])
end

task_list = tasks.join("\n")

Slack.configure do |config|
  config.token = scheduler["slack_token"]
end

line = "---------------------------\n"
text = case Time.now.hour
       when 11 then "#{line} today tasks confirm \n #{line} #{task_list}"
       else
         'Error!!'
       end

Slack.chat_postMessage(text: text, channel: scheduler["channel"], link_names: true, username: 'scheduler')
cronに登録
$ cat /home/[ユーザー名]/slack_bots/config/schedule.rb
every '30 23 * * 1-5' do
  command '/home/[ユーザー名]/slack_bots/time_signal.rb'
end

$ bundle exec whenever --update-crontab

結果

出来たー!! 表示のさせかたはもう少し修正が必要ですが、とりあえず欲しい物は作れました。

気になってるところ

  • とりあえず動けば良い程度のコードになっているので、もっときれいに書き直したいですね。(curlを叩くところとか)
  • WunderlistのAPIを叩くためのtokenの発行の仕方が結構わかりにくかったので、もしかするとそこで結構詰まるかもしれないです・・・

参考リンク

タスク管理ツール WunderlistのAPIで遊んでみた - Qiita

Wunderlist をコマンドラインから操作する Wunderline - WebDelog

10分コーディング! Rubyでつくる Slack時報 | Money Forward Engineers' Blog