【Golang】RequestからQueryStringを取得するには

最近Golangでコマンドラインツールを作りたくて、Golangのサンプルコードとかを動かしていろいろ遊びながら覚えているところなのですが、たまたまEchoサーバーのプログラムがあったので試したのですがすごく簡単にかけますね!

そのとき、リクエストからQuery Stringをどう抜き出すんだろと思って試しに書いてみました。

package main

import (
    "net/http"
    "log"
    "fmt"
)

func main() {
    http.HandleFunc("/", handler)
    log.Fatal(http.ListenAndServe("localhost:8000", nil))
}

func handler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "%s %s %s\n", r.Method, r.URL, r.Proto)
    v := r.URL.Query()
    if v == nil {
        return
    }
    for key, vs := range v {
        fmt.Fprintf(w, "%s = %s\n", key, vs[0])
    }
}

r.URL.Query()type Values map[string][]string を受け取ることができるので、rangeでループ回して表示しています。

個別にキーを指定して取得したい場合は以下のようにキーを指定してあげれば取得できるはず

r.URL.Query().Get(キー)

EC2のユーザーデータ内でcloud-initとシェルスクリプトを使いたい

こんにちは。こんばんは。

たまたま、CloudFormationのテンプレートから起動されるEC2のユーザーデータを利用して、インストールしておきたいモジュールがありました。

ユーザーデータには、cloud-initシェルスクリプト で何らかの処理を書くことができるのですが、 テンプレートにはすでにcloud-initの形式で書かれており、シェルスクリプトを書こうとするとエラーとなりユーザーデータで書いた内容は実行されません。

EC2のユーザーデータ内で、cloud-initシェルスクリプト を併用したいけどそんなことができるのかといろいろ調べていくうちに、この記事に行き着きました。

cloud-initでシェルスクリプトとcloud-configを同時に使う

はい、やりたかったことはこれです!!

ってことで、実際に自分でやってみた手順を書いていきたいと思います。

cloud-utils パッケージをインストールする

まず、cloud-utils パッケージをインストールしましょう。

$ sudo yum install cloud-utils

※ 上記は、Amazon Linux AMI 2018.03.0 から作成したEC2内で作業をしています。

cloud-init 形式で書いてファイルを作成

viを立ち上げてファイルを作成します。

$ vi cloud-config.txt

そして、以下の内容をコピペして保存してください。

#cloud-config
packages:
  - sl

runcmd:
  - echo "HELLO Cloud Config"

シェルスクリプトで書いてファイルを作成

viを立ち上げてファイルを作成します。

$ vi shell.txt

そして、以下の内容をコピペして保存してください。

#!/bin/bash -xe

touch /home/ec2-user/create-by-shellscript.txt
echo "HELLO ShellScript" >> /home/ec2-user/create-by-shellscript.txt

write-mime-multipart で MIMEマルチパート形式のファイルを作成

先ほど作成した、cloud-config.txtshellscript.txt を使って、 MIMEマルチパート形式のファイルを作成します。

以下のコマンドを実行してみましょう。

$ write-mime-multipart --output=output.txt cloud-config.txt:text/cloud-config shell.txt:text/x-shellscript

するとカレントディレクトリに、output.txt が作成されていると思います。

ファイルの内容を確認するとこのように記述されています。

Content-Type: multipart/mixed; boundary="===============2433150631494388583=="
MIME-Version: 1.0

--===============2433150631494388583==
Content-Type: text/cloud-config; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="cloud-config.txt"

#cloud-config
packages:
  - sl

runcmd:
  - echo "HELLO Cloud Config"

--===============2433150631494388583==
Content-Type: text/x-shellscript; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="shell.txt"

#!/bin/bash -xe

touch /home/ec2-user/create-by-shellscript.txt
echo "HELLO ShellScript" >> /home/ec2-user/create-by-shellscript.txt

--===============2433150631494388583==--

このファイルの内容をそのままEC2のユーザーデータにコピペして起動してあげると、 処理が自動で実行されます。

f:id:ryskit:20180516203222p:plain

立ち上げたインスタンスにSSHで入って確認してみましょう!

ユーザーデータの内容が実行されたかどうかは、/var/log/cloud-init-output.txt を見れば確認できます。

$ less /var/log/cloud-init-output.log
:
:
Existing lock /var/run/yum.pid: another copy is running as pid 2597.
Another app is currently holding the yum lock; waiting for it to exit...
  The other application is: yum
    Memory :  38 M RSS (286 MB VSZ)
    Started: Wed May 16 11:30:54 2018 - 00:00 ago
    State  : Running, pid: 2597
Resolving Dependencies
--> Running transaction check
---> Package sl.x86_64 0:5.02-1.6.amzn1 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

================================================================================
 Package     Arch            Version                   Repository          Size
================================================================================
Installing:
 sl          x86_64          5.02-1.6.amzn1            amzn-main           13 k

Transaction Summary
================================================================================
Install  1 Package

Total download size: 13 k
Installed size: 15 k
Downloading packages:
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  Installing : sl-5.02-1.6.amzn1.x86_64                                     1/1
  Verifying  : sl-5.02-1.6.amzn1.x86_64                                     1/1

Installed:
  sl.x86_64 0:5.02-1.6.amzn1

Complete!
Cloud-init v. 0.7.6 running 'modules:final' at Wed, 16 May 2018 11:30:58 +0000. Up 25.17 seconds.
HELLO Cloud Config
+ touch /home/ec2-user/create-by-shellscript.txt
+ echo 'HELLO ShellScript'
Cloud-init v. 0.7.6 finished at Wed, 16 May 2018 11:30:58 +0000. Datasource DataSourceEc2.  Up 25.50 seconds

正しくログが吐かれていますね!!

CloudFormationのEC2インスタンスのユーザーデータでも同じことをしたい場合は、 作成したMIMEマルチパート形式のファイルの内容を同じようにコピペしてあげれば動作します。 ただし、JSON形式だとダブルクオテーションで一文一文を囲ってあげないと動作しないと思うのでそこは注意してくださいね。

では!!

Railsのbelongs_toに指定できるoptional: trueとは?

今年1月に転職して新しい環境で働き始めていて、そこのプロジェクトではRuby on Railsを使っています。

今までRuby on Railsでサービス等を作った経験があまりがなくRailsを知る必要が出てきて、最近出版された「Ruby on Rails5の上手な使い方」という本を買いました。

この本にはモデルのbelongs_to に以下のようなオプションが書かれていました。

class Customer < ApplicationRecord
  has_many :orders
end

class Address < ApplicationRecord
  belongs_to :customer, optional: true
end

この optional: true ってなんなのか。

結論から言うと、belongs_toの外部キーnilを許可するというものです。

上記のコードであればAddress.customer_idが外部キーになり、値がセットされていない場合はバリデーションではじかれますが、optional: trueを設定しておくと、外部キーがnilであってもDBに保存できます。

ただDBの設計上、外部キーのnilを許可することが少ない気がするので、あまり使う設定ではないかもしれません。

Work Rules!を読んだ

グーグルの人事として働いている著者が書いた本

グーグルがなぜ、どう動いているかの著者なりの解釈を書いた内容

第1章 創業者になろう

自由度が高い - 自由裁量権を与えられる

トップダウン、階級制、指揮統制を特徴とする経営モデル - 自由度が低い環境は消えてなくなる

グーグル的アプローチでは、権力と権威をマネジャーから社員へ譲り渡すように意識している。

グーグルのマネジャーが自分の一存では下せない決定の一例

  • 誰を雇うか

  • 誰を解雇するか

  • ある人の業績をどう評価するか

  • ある人に関する昇給、ボーナス、株式付与をどれくらいにするか

  • 優れた経営手腕への褒賞を誰に与えるか

  • コードはどの時点で、ソフトウェア・コードベースに組み込める品質となるか

どうすれば業績が改善するか

  • 企業が社員に権限を与えるプログラムを実行したとき、仕事に必要なこと以外を学ぶ機会を社員に提供したとき、社員のチームワークへの信頼を高めたとき、あるいはこれらの施策を組み合わせて実行したとき。

第2章 文化が戦略を食う

グーグルがどんな仕組みで動いているのか、あるいはグーグルでこうした経営手法を選ぶのかを理解するには、グーグルの文化を定義する3つの要素の探求する必要がある。

  • ミッション

    • グーグルのミッションは、簡潔で多くのことが話題になっていない

    • ミッションは事業目標ではなく道徳

  • 透明性

    • いかなる情報も共有できないと想定するのではなく、あらゆる情報はチームと共有できると想定すること。情報の制限は意識してようやくやるべきことであり、そうするには十分な理由がなければならない。オープンソースにおいては、情報の隠蔽はカウンターカルチャーなのだ。

    • 「社員は我が社の最大の資産」だというなら、オープンを原則としなければならない。

  • 発言権


  • 会社の経営方針について、社員に対して実際の発言の機会を与えることを意味する

  • グーグルの人事慣行の多くは、社員からの発案によるもの

  • 社員にアイデアを表明する権利を与えることは、質の高い意思決定を促し、組織効率を高める重要な要因

  • 社員に遠慮なく話してもらうと、意思決定の質、チームのパフォーマンス、組織のパフォーマンスに対してプラスの効果がある

  • 議論しやすい環境を作る

  • 人は動機づけでパフォーマンスは変化する

  • OKR ( Objectives and Key Results: 目標と主要な結果 )

第3章 レイク・ウォビゴンの幻想

  • 採用に時間をかける

  • 自分より優秀な人物を雇え

  • 賢いというだけで雇ってはならない

第4章 最高の人材を探す方法

  • あらゆる社員をリクルーターに変えるべく、人材の紹介を依頼すること

  • 最高のネットワークを持つ人々に優秀な人材の確保にもっと時間を割いてもらえるように頼む

  • 積極的に人材を探すための実験を行うこと

  • 最高の人材の注意を引くために、突拍子もないことも恐れずやってみる

第5章 直感を信じてはいけない

  • 第一印象を与えるチャンスは一度だけ(最初の5分)
  • あなたは受験者を評価したいだけでないということ。彼らがあなたと恋に落ちるようにしたいのである。受験者に素晴らしい体験をしてもらい、関心事を語ってもらい、人生で最高の1日を過ごしたような気分で帰ってもらいたい。

  • グーグルで成功するかの4つの明確な属性

    • 一般認識能力

      • 当然ながら、新たな状況に学んで適応できる、頭のよい人材が欲しい

      • 求職者が実生活において困難な問題をどう解決してきたか、どう学ぶか

    • リーダーシップ

      • 創発的リーダーシップ
    • グーグル的であること

      • 愉快なことを楽しむ

      • ある程度の謙虚さ

      • きわめて誠実

      • 曖昧さを楽しむ余裕がある

    • 職務関連知識

自己複製する採用マシーンをつくるには?

  • 求める人材の質の基準を高く設定する
    • 妥協はいけない
  • 自分自身で採用候補者を見つける
  • 採用候補者を客観的に評価する
    • 採用候補者の部下や同僚になる者を面接に加える
  • 採用応募者に入社すべき理由を伝える

第6章 避難所の運営は避難者に任せる

  • 最高のグーグラーは、理にかなう場合には自分の判断でルールを破る
  • マネジャーは権力を蓄え、行使する傾向にある
  • 社員は命令に従う傾向にある
  • グーグルでは肩書以外でヒエラルキーを表したり強化したりしたりするものを排除した
  • 最上級幹部であっても新入社員と同じ便益、特典、資源しか受け取らないということ
  • 権力の象徴や権力者のような態度を最小限に抑えるだけでなく、マネジャーの意見ではなく、データにもとづいて意思決定する
  • 社員が自分の仕事や会社の指針を定める方法を見つける
  • 期待は大きく

第7章 誰もが嫌う業績管理と、グーグルがやろうと決めたこと

  • 評価や報酬ではなく、個人の成長に焦点を合わせることによって業績を改善する

業績評価のために - 目標を正しく設定する - 同僚のフィードバックを集める - 報酬についての話し合いと人材育成についての話し合いを分ける

第8章 トップテールとボトムテール

  • 成長のためのフィードバックと評価のフィードバックは絶対に分けるべき
  • 困っている人に手を差し伸べる
  • 最高の社員をじっくり観察する
  • 調査やチェックリストを使って真実をあぶりだし、改善するよう社員をせっつく
  • 自分のフィードバックを公表し、至らなかった点について改善するよう努力して範を垂れる

第9章 学習する組織を構築しよう

  • 学習に費やす時間の長さではなく、時間をどのように費やすかが重要
  • 状況を確認しながら、小さな修正を重ねて改良する
  • 反復と集中
  • 行動を変えるプログラムに投資する
  • 組織やチームの学習効率を上げる方法のひとつは、学習するスキルを細かい要素に分けて、具体的なフィードバックを即座に返す
  • デリバレイト・プラクティス(熟考した練習) - 講義をしやすい量に分割して、明快なフィードバックを提供し、繰り返し学習する
  • 社内で最も優秀な人を教師にする

第10章 報酬は不公平でいい

  • 報酬について
    • 報酬は不公平に
    • 報酬ではなく成果を称える
    • 愛を伝え合う環境づくり
    • 思慮深い失敗に報いる
  • 公平な報酬とは、報酬がそのその人の貢献と釣り合っているということ
  • インセンティブや目標達成も重要だが、熟慮した上でリスクを取る行為自体も賞賛すべきだ。失敗したときこそ賞賛しないと、誰もリスクを取らなくなる
  • 社内の摩擦を恐れず、不公平な報酬を払う。パフォーマンスのべき分布を反映して、報酬の決め方に幅を持たせる

第11章 タダ(ほぼタダ)ほどステキなものはない

福利厚生のプログラムなど

  • グーグルの社員を対象とするプログラムには3つの目標がある
    • 効率を高め、
    • コミュニティを形成し、
    • イノベーションを促すことだ
  • イエスという理由を見つけよう。社員の提案を認めれば、より活気にあふれた楽しい職場になり、生産性が上がるという見返りがあるだろう
  • 社員の生活の負担を減らす
  • 人生で最悪の出来事はめったに起こらないが、起きた時は社員に寄り添う

第12章 ナッジ/選択の背中を押す

  • 所属する組織の大きさにかかわらず、環境を作る際は熟慮した方がいい。目的は社員に自分の人生をよりよくしようと思わせることだが、そのために彼らの選択肢を奪うのではなく、よい選択をしやすい環境をつくるのだ。
  • 「である」と「であるべき」の違いを理解する
  • 小さな実験を数多く行う
  • ナッジは強制ではない

第13章 人生は最高のときばかりじゃない

失敗に直面したとき

  • 自分の間違いを認め、隠そうとしない
  • あらゆる方向に助言を求める
  • 壊れたものは修理する
  • 間違いから教訓を学び、それを伝える

第14章 あなたにもあしたからできること

自由度の高い環境を手に入れるために、チームや職場を変える10のステップ

  1. 仕事に意味を持たせる
    • 日々の業務を超越して、自分がやっていることを忠実に反映するアイデアや価値観と、仕事の目的を結びつけよう。
  2. 人を信用する
    • 人間は基本的に善だと信じるなら、信念にしたがって行動する。
    • 小さなことから始めよう
  3. 自分より優秀な人を採用する
    • 採用の質で妥協することは、間違い
    • 客観的な採用基準を持つ
  4. 発展的な対話とパフォーマンスのマネジメントを混同しない
    • つねに発展的な対話を心がけ、安心と生産性につなげていこう
  5. 「2本のテール」に注目する
    • 会社やチームで最も優秀な人を観察してみる
    • 最も優秀なプレイヤーを手本にチェックリストをつくり真似てみるだけでなく、教師になってもらう
  6. カネを使うべき時は惜しみなく使う
  7. 報酬は不公平に払う
  8. ほとんどの仕事のパフォーマンスはべき分布に従う
  9. 褒めるときは公の場で惜しみなく褒める。チームの業績を称え、重要な教訓を学んだ失敗にエールを
  10. ナッジ ― きっかけづくり
  11. 高まる期待をマネジメントする
  12. 楽しもう (1に戻って繰り返し)

人事オタクのためのあとがき

4つの基本原則にのっとってピープル・オペレーションズを気づいてきた

  1. ニルバーナを追いかける
  2. データを使って未来を予測し、形作る
  3. 飽くなき向上
  4. 型にとらわれないチームづくり

gitで削除してしまったファイルをまとめてcheckoutする

タイトル通り。

手違いでgit管理下にある大量のファイルを消してしまって元に戻したいときに便利です。

awk を使ってまとめてステータスがdeleteのものを元に戻してあげましょう!

git status -s | awk '/^ D/{print "git checkout "$2}' | sh

Dの部分を、他のステータスの頭文字に変えてあげれば応用できますね!

オブジェクト脳のつくり方―Java・UML・EJBをマスターするための究極の基礎講座を読んだ

最近、仕事でコードを書いていて、将来拡張・保守しやすくて、わかりやすいコードをどんどん書けるようになりたいと思っていたところ、本屋で「オブジェクト脳のつくり方」という本を見かけて、さくっと読めそうだったので買ってみた。

内容としては、オブジェクト・クラス・継承・カプセル化・ポリモーフィズムとはなんぞやという話から、デザインパターン3種ぐらい(Factory Method, Composite, Template Method)を試しに書いてみよう、オブジェクト指向で開発するメリット、設計(ユースケース図、クラス図、オブジェクト図、シナリオ)、JSP、EJBあたりの話が出てくる。

感想

最初のオブジェクトとはなんぞやから実際にデザインパターンを書くところらへんまでは良い復習になるな!ぐらいに思ってたが、設計図やらJSP、EJBやらの話が出てき始めたあたりから、オブジェクト指向の話とずれてきてないかという違和感がでてきた。

前半は、プログラミングを始めてオブジェクト指向ってなんや?って思ってる人には得るものが大きいと思う。ただ正直、後半は読まずにサッと流しても大丈夫な内容だ。

業務でもどうコードを書くのがベターなのか迷うときがあるので、デザインパターンを軽く押さえておくと良さそうな気がするので、結城浩さんのデザインパターン入門あたりを読んでみようと思う。

あと関係ないけど、オブジェクト指向設計実践ガイドは理解しやすくておすすめです。

WordPressで任意のサムネイル画像サイズを追加・サムネイルを再生成する方法

f:id:ryskit:20161113021259j:plain

WordPressでサイトを作っていると、記事の一覧を表示するときにアイキャッチ画像を表示することが多いと思います。

その際、任意のサイズのサムネイル画像を表示したくなるのが人情です。

この記事では、「任意のサイズのサムネイル画像を生成する方法」とWordPressでサイトを構築して運用し始めた後、新しくサムネイル画像のサイズを追加して再生成する方法をご紹介します。

任意のサイズのサムネイル画像を生成する方法

WordPressで画像をアップロードすると、

  • サムネイル「150 x 150px」
  • 中サイズ「300 x 225px」
  • フルサイズ「600 x 450px」

上記の3パターンで自動的に画像が生成されます。

これはデフォルト設定の場合で、これ以外のサイズで画像をリサイズ・切り出して欲しい場合は少し手を加える必要があります!

といっても簡単で、テーマにある functions.php というファイルに一行加えるだけ。

<?php add_image_size( $name, $width, $height, $crop ); ?>

引数の$nameは、新しい画像サイズの名前を指定します。 $widthは、切り出したいサムネイル画像の幅をピクセル単位で指定します。 $heightは、切り出したいサムネイル画像の高さをピクセル単位で指定します。 $cropは、画像を切り出すかどうか。デフォルトはfalseで、指定の幅または高さに合わせてリサイズ、trueの場合は、指定のサイズで切り抜きます。

参考サイト:

関数リファレンス/add image size - WordPress Codex 日本語版

kotori-blog.com

例えば、functions.phpに以下のように画像サイズを指定したとします。

<?php add_image_size('post_100x100_thumbnail', 100, 100, true); ?>

指定した後、画像をアップロードすると、100x100pxで画像が切り出されます。

100x100pxで切り出された画像を利用する場合は、こんな感じで指定します。 ※ループでpostを回している場合

<?php the_post_thumbnail('post_100x100_thumbnail'); ?>

めっちゃ簡単です!

サムネイル画像を再生成する方法

WordPressでサイトを運用し始めたあと、サイトの改修などでサムネイル画像のサイズを新しく追加してそちらを使いたい場合があります。

そのときに問題になるのが、過去にアップした画像の新しいサムネイル画像をどう生成するのかという問題。

いまからアップロードする画像は指定したサムネイルの画像サイズで生成されるのですが、過去の画像については改めて画像をアップロードするなどしないといけません。

とてもめんどくさい......

でも、WordPressはプラグインが豊富!解決してくれるプラグインがありました!

ja.wordpress.org

使い方もめちゃ簡単!

まず、プラグインの新規追加からregenerate-thumbnailsで検索してインストールして有効化します。

すると、サイドバーのツールにRegen. Thumbnailsと表示されるようになるのでクリックします。

f:id:ryskit:20161113015751p:plain

regenerate-thumbnailsの管理画面に遷移すると、Regenerate All Thumbnails表示されたボタンがあるのでクリックするとサムネイル画像の再生成が始まります。

f:id:ryskit:20161113020618p:plain

これで、functions.phpに追加した新しいサイズのサムネイル画像が再生成されるはずです。

最後に

いかがでしたでしょうか?

僕はあまり使うプラグインを増やしたくない方なので、今回はfunctions.php に一行追加して任意のサイズのサムネイル画像を生成する方法をご紹介しました!

WordPressにはプラグインがたくさんあるので、サムネイル画像のサイズを管理画面から登録できるプラグインとかありそうですよね。 なので、今回の記事でfunctions.phpに書き込むのは抵抗あるなって方はそういうプラグインを探してみるのも楽しそうですね!

では!