Gitを教えたときの話

前置き


事の発端はある人と作業してたことから始まりました。。。
というのも、自分が海外に行ってるいる間、作業をお願いしていました。

作業をお願いしていたのはいいのですが
彼は普段使っていないGitを使ってみたかったようです。

今回は、そのとき伝えたことをネタにします。
もっとネタにするものはありますが(ぉぃ

基本操作以外に覚えて欲しいと伝えたこと


  • GitのGUIツールを捨てろ(言い過ぎだと思うし、賛否両論あると思っている)
  • 状態は常に確認するようにしよう
  • ファイルを編集前状態に戻すやり方
  • マージやリベースで、ファイル競合状態になったときの対処(エラーログとか読んでみる)
  • ヘッド位置の意識
  • ヘッドの操作方法やヘッドの位置がどこにあるのか
  • 落ち着いてブランチを切って、Git操作を試してみる(カジュアルに作れるので、作ったブランチで操作を試してみる)
  • masterでのファイル編集をやめる

コミットの取り消しや歴史の改変とかも覚えてて貰いたいけどな

教えたはいいけど、自分もまだまだ使いこなせてないのでは?と思ったりしてます。

伝えた元に戻す系のコマンド類


元に戻し方とかそんな感じのことを以下にメモレベルで記載

ファイルをインデックス(元々のヘッド状態)の状態に戻す

1
$git checkout -- <元に戻したいファイル>

ワークツリーとインデックスをコミットIDに指定した状態に戻す

1
$git reset --hard <コミットID>

現在のコミットからブランチを作成する
作業はここでしちゃいましょう。

1
$git checkout -b <ブランチ名>

リベースでおかしなこと(ファイルの競合とか)が起きた時に元に戻す

1
$git rebase --abort

ここに書いた以外のやり方なんていくらでもあるので、参考程度で。

Linux上にあるユーザーアカウントの追加と削除をする

すごくド基礎なのですが・・・。
ユーザーアカウント削除ってどうやるんだっけな?ってなったのでついでにメモしておく。

ユーザーアカウントの追加


基本中の基本ですね。
以下のコマンドのような感じで追加します。

1
$useradd -u 500 -g wheel -m kurobara

以下の表によく使用するオプションを記載します。

オプション 意味
c コメント ユーザーのコメントを設定
d ディレクトリ ユーザーのログインディレクトリを指定
e mm/dd/yy ユーザーの有効期限をmm/dd/yy形式で指定
g グループ ユーザーの所属するイニシャル・グループを指定
G グループ ユーザーの所属するグループを指定します(「,」で複数指定可能)
u ユーザーID ユーザーのユーザーIDを指定
s シェル ユーザーのログインシェルを指定
m ホームディレクトリの作成を自動で行う

ユーザーアカウントの削除


以下のコマンドでユーザーアカウントの削除ができます。
なお、オプションにrを付与すると、ホームディレクトリまで削除してくれます。
但し、他のファイルシステムにあるファイル等は探しだして手動で削除する必要があります。

1
$userdel <ユーザーアカウント名>

常識ですね(ぉぃ

コマンドで暗号化Zipファイルを作成する

暗号化Zipファイル作成


大概GUIありのツールでやってしまうのですが、必要に駆られたのでコマンドでやることになりました。
以下のようにzipコマンドのeオプションを使うだけで簡単にできます。

1
$zip -e <zipファイル名> <圧縮対象のファイル>

恥ずかしながらあんまりやらないので、いざというときには忘れてしまいます。

EmacsのScratchバッファに設定を追加してみた

Emacsのscratchバッファってすごく便利ですよね。

特に以下のことによく使います。

  • ちょっとしたメモしたり
  • URLメモを取ったり
  • ちょっとした引用メモの整形とか
  • マクロの実験とか

まぁよく使うわけです・・・ が、ついうっかりでEmacsを終了したりとか、Emacs本体がゾンビプロセスになったりとかでロストしてしまうことがあります。
自分はこれでよく泣きました(> <;)

また、メモを保存しておこうと思った時にバッファの先頭にある初期メッセージが鬱陶しくなってきます。

今回は、これらの問題を解決してしまいます。

まずは、scratchの初期メッセージ消去します。
以下の内容を「.emacs/init.el」に追加します。

1
(setq initial-scratch-message "")

この設定を加えて、Emacsを再起動するとscratchバッファの初期メッセージがなくなります。 即座に反映したければ、評価してもいいとおもいます。

次に、Emacsが終了してしまったときにScratchバッファの保存と再起動時にScratchバッファの内容を復元する方法ですが・・・

以下の内容を「.emacs/init.el」に追加します。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
(defun save-scratch-data ()
  (let ((str (progn
               (set-buffer (get-buffer "*scratch*"))
               (buffer-substring-no-properties
                (point-min) (point-max))))
        (file "~/.emacs.d/backups/.scratch"))
    (if (get-file-buffer (expand-file-name file))
        (setq buf (get-file-buffer (expand-file-name file)))
      (setq buf (find-file-noselect file)))
    (set-buffer buf)
    (erase-buffer)
    (insert str)
    (save-buffer)
    (kill-buffer buf)))

(defadvice save-buffers-kill-emacs
  (before save-scratch-buffer activate)
  (save-scratch-data))

(defun read-scratch-data ()
  (let ((file "~/.emacs.d/backups/.scratch"))
    (when (file-exists-p file)
      (set-buffer (get-buffer "*scratch*"))
      (erase-buffer)
      (insert-file-contents file))
    ))

(read-scratch-data)

上のEmacsLispが何をやっているかと言うと・・・
終了時にScratchの内容をファイルに書き込み、起動時に書き出したScratchバッファの内容を読み込みしているだけです。

これで、Scratchバッファをちょっとしたメモ帳として大いに活用できますね。

Go Conference 2013 Springに行って来ました。 #GoCon

午前中と午後はモクモクとコード書いてました。。。
XML周りの処理とかちょっとしたい感じだったので書いてみました。

「XMLの構造が分かっていたら、 Unmarshal関数を使ったほうがいいね。」

というのが感想です。
真面目にDOMを用意してみるとかなりコード書かないといけないので辛い感じ。
個人的には、XMLをDOMで操作するならRubyを使います(ぉぃ

動作速度まで測ってませんが、多分Goのほうが圧倒的速度で処理してくれるでしょう・・・。
機会があればやってみます。

以下、セッションメモ

Goでの思考方法


class = type object = value method attache any type interface はmethod(?)

# 途中から何かしてたので聞き逃した。 # 何処かにスライド上がってないだろうか?

Go言語で作るWebアプリ


Webサーバ作るときは、以下のやり方が基本

  • http.Serverに渡して、http.Handlerで処理する
  • ListenAndServerで起動する
  • 複数のハンドラを設定できる(http.serverMux型)
  • ハンドラを実装するのは大変なのでhttp.HandlerFuncを使う
  • serverMuxを作るのがめんどいなら、DefaultServerMuxというグローバル変数を使うといい
  • 静的なhtmlを表示する場合は、http.FileServerを指定してやればいい

Restful APIを作る

  • GoWebを使えば、楽にできる
  • リクエストの受け取りやレスポンスをxmlやjsonで返せる
  • ルーティング管理ができる
  • Controllerを作るだけでいい
  • インタフェースを実装すればよい感じ

テストパッケージやnginxと連携とかテンプレートエンジンとかあるので話したかった・・・

GAE/Goの話


  • main関数はAppEngineのRuntimeがやるので、実装しなくてもよい
  • 構造体にデータ(kind)を作ってしまう
  • keyを作成する(AppEngineユーザーにはお馴染みの処理)
  • それからデータストアにputする
  • SDKはPythonが起動→Goで書いたアプリ起動の流れ
  • PythonとGoが連動してるのでGo単体のテストは辛い
  • AppEngineとGoは安心して使いづらい(単体テストが厳しいため)
  • Spin-Upは相当早い(Python 約386ms,Go 約48ms)
  • 使用メモリは、Pythonに比べて少ない
  • Spin-Upと省メモリなので、Goは優位かも
  • I/O待ちがあるので、常にGoが早いと言えない
  • 最初からAppEngineに入る場合には選択肢に入るかも
  • 無理に既存のものを載せかる必要性はない
  • Pythonでメイン処理を書いて、GoをBackground処理にするという方法もアリ

# AppEngineで動かしてるオレオレのサービスの追加機能はGoで実装してみようかなぁ

GoRoutine&Channelでの並行処理


  • 並行処理のアプローチは「メモリのシェア」、「メッセージパッシング」の2つが大体使われる
  • GoはCSPとパイ計算がベースになっている
  • slectとclosureも並行処理で使える
  • ユーザーランドだと関数のまえにgoをつけると、goroutineが実行できる
  • gotoutineの終了は、処理が最後まで行った時、return文やgo_exitでできる
  • channelでgoroutine同士でメッセージできる
  • メッセージのバッファサイズも決めれる
  • goroutineを複数やる場合、waitegroupを使えばいい
  • Worker
  • Selectは読み出しがブロックするのを待っている
  • channelにはバッファ機能があり、バッファサイズ以上を書き込もうとするとブロックする(セマフォっぽいイメージ)
  • Goroutineでcoroutineっぽいものもできる
  • 複数コアを使う場合、自分で明示的にコア設定してやる必要がある
  • netchanが昔はあったが、今はdeprecatedになっている。(I/Fが複雑になりすぎたかららしい。ノウハウ貯まれば復活するかも)

\ # channelのcloseはレシーバ側で行うっぽい?

goroutineのスケジューラの話


  • スタックコントローラーやプロセスコントローラーで実行されてる
  • 上を実現するため、Goは一部’アセンブラで書かれている
  • スケジューラ:G(goroutine),M(ワーカースレッド、マシン),P(プロセス。MAXPROCSに指定できる最大値はこいつ)
  • GOMAXPROCSは、スレッド数と同じではない(異なることもある)
  • スケジューラを解析していた方のメモに詳しく流れが記載されています
  • go buildにsオプションをつけるとどんなランタイム呼ばれてるのかわかるようになる

Goのよいところ


最初の気に入らないところ

  • 第一印象、人形もコードもキモい!!違和感があった
  • 似てるようで違うところが多くてキモい(C++/Java/Pythonと比較して)

良かったところ

  • 読みやすい
  • シンプルな仕様(最近の言語は、便利機能多いけど複雑すぎる)

Goを書き慣れてくると・・・
印象が変わる!!

  • 他の言語の複雑な型宣言にムカつく(複雑になってくるとGoのほうが有利)
  • ダックタイピングも複雑になってくると、動くことはわかるけどコードを読むときによく分からなくなる(Goだとinteeface型を作ればややこしくなくなる)
  • オブジェクト指向もGoのほうが便利(PythonもJavaもクラス設計をしっかりしないといけない)
  • スコープも調べるのが大変だし、アクセスしたいものもアクセスできないとかある(Goは大文字だとpublicそれ以外はpackage private)
  • 未使用なコードもGoだとビルド時に検出してくれる(dependencyを残すと大規模開発になるとメンテが大変になる。どうしてものこしたければ「_」をつける)
  • エラー処理は、javaとかpythonはExceptionにしたがる(変なGoToしてるだけ、それは多値返せば、処理の流れは破綻しないでしょ)
  • panicは本当にどうしようもないときにだけ使用する。普通はエラーできっちり返してあげる設計にするべき
  • Goで解決したいものの多くは、サーバとかのインフラの並列処理

# 話聞いてると頷ける話で、確かに個人的にJavaはうざいと思うのは事実・・・ # 個人的にAPIのサンプルがドキュメントに載ってたらいいなぁなんて思いました。。。

goでゲームを作る


  • 画面、音、入力のライブラリがある
  • なんか似たようなもので複数あるっぽい(描画だけでもGoGLとかglとか)
  • GoGL,go-flwでできる

大まかな流れ

1 初期化で、キー入力とウィンドウ処理をしてやる(main関数ではこれだけにする) 2 初期化のタイミングでウィンドウの設定をしてやる 3 初期化以降はメインループを実行する 4 ゲームのランを行う(ウィンドウが開いてる間実行するように実装する) 5 フレームに対して描画を行う 6 ゲームを実装してる本体でキーボードとかの入力を受け取るようにする 7 描画メソッドではひたすら描画の実装をしてやる

A Case Study


  • Rubyにはいいところもあるが良くないところもある
  • CloudFundryでEventMachineをRubyでやっていた
  • Rubyは特に好きだ

設立したベンチャー企業では + 複数のOSサポート + システムのスケールもさせたい + そのためGo vs Node.jsになった

Node.js

  • v8ランタイム
  • イベント駆動
  • JSベース
  • ランタイム依存
  • JSベースなので(コールバック地獄)
  • 実験的な機能が・・・

Go

  • 設計メンバーが良かった
  • 同期モデル
  • プラットフォームのサポートがよかった
  • 新しい言語
  • 標準ライブラリはどう使えば?
  • GCやスケジューラが隠れている

いいところが多いので15分でGoを採用することになった(チームで決めた)

  • 学習が簡単だった
  • 標準でライブラリが揃っている
  • なぜGoなのか(聞き取れなかった)
  • GoのGCはスタックベースなので良かった。
  • 暗号化通信はOpenSSLのラッパーを用意した(パフォーマンスの問題?)
  • 文字列とバイト配列の変換
  • SQLは低レベルすぎて辛いのでORMとドライバーは自前で用意した
  • mapも遅い。多分1.1で治るはず・・・
  • いけてない面もまだまだあるけど、Goを選択したのはよかった
  • GoはIaaSやPaaSで主役になれる!!

まとめ

  • GoはGoogleが採用しているだけあってシステム書くには向いている
  • Goは標準ライブラリが揃っている
  • テストやドキュメントもビルトインである
  • 学習も楽にできる
  • GCもStackベースなので遅延が起きることは少ない
  • いくつかの問題は1.1で解決されることに期待!!

# 最後のセッションのこいつはうろ覚え(聞き取りながらで辛かった)

感想


Goに関してのいいところや悪いところを吸収できたかなーと思う。
密度が濃い一日だったと思いました。   なによりGoでモクモクできたのが良かったなーとおもいます。(まともに書いたのはアーリーアダプター以来だった思う。。。) コンパイルと実行が下のコマンドでできることには驚いた。(昔は8g,8lとかしてたコンパイルしてた記憶)

1
$go run <プログラムファイル>

仕事でシステム周りの実装するならGo言語をぜひとも採用させたいですね。。。

rsyncを使って自前サーバでOctpressを運用する

Octpressが便利すぎ。。。
Bloggerとは何だったんだって感じです。

どうも、どうもこんにちは。kurobaraです。

便利すぎるんで、

「ちょっと、外部に公開できないけどーみたいな感じで何でも書けるようなブログ」

欲しくなるわけですよ。(主に会社で、ですが・・・)

結論から先に言っちゃうと、自前サーバでOctpressを動かせます。
Apacheのディレクトリ制限を噛ますことでアクセス制限なんてこともできます。

という訳で、Octpressを自前サーバで動かす方法をやってみます。

準備


思いつく感じのこと

  • クライアントから自前のサーバにSSHでアクセスできること
  • クライアントにrsyncがあること
  • クライアントでOctpressが動作すること

こんな感じ、移行で設定します。

Rakefileの編集


Rakeコマンドを使ってる訳なので、deploy先を変更するため以下のように編集します。

  • 「ssh_user」を実際のユーザー名とサーバ名に変更します
  • 「document_root」でサーバ配置のディレクトリを指定します
  • 「ssh_port」はデフォルトで22ですが、必要に応じて変えます
  • 「deploy_default」をpushからrsyncに変更します。
1
2
3
4
5
ssh_user       = "user@server"
ssh_port       = 22
document_root  = "/var/www/html/"
rsync_delete   = true
deploy_default = "rsync"

ぶっちゃけ、自前サーバで動かすだけならこれで終わりです。
が、これだけだと寂しいのでサブディレクトリで動作するようにしてみます。
# 当たり前ですが、普通はサブディレクトリ単位でコンテンツをApacheに配備すると思います。

サブディレクトリ運用


http://<サーバURL>/hoge のようにサブディレクトリ運用する場合は、以下のようにします。

  • サブディレクトリを作成します
1
$rake set_root_dir[hoge]
  • _config.yamlでサブディレクトリを追加します
1
url: http://<サーバURL>/hoge
  • Rakefileのdocument_rootをサブディレクトリに変更します
1
document_root = "/var/www/html/octopress"

あとは、Apache2でサブディレクトリの設定を施してやれば動作します。
認証を付けたければ、認証の設定をすれば認証付きのBlogになります。

これで、要件を満たせたので作業メモとか残せて幸せになれますね。(多分)

万葉.rbに参加してきました。#everyrb

参加メモメモ。

オープニング


Matzからの挨拶。
楽しい設計の言語が真面目に仕事になって嬉しい。
万葉をよろしく!!

基調公演(島田さん)


言葉は軽く聞こえるけど、会社経営だとすごい!!

最近思う「コミュニティと会社の私」

  • 会社は孤立している。契約とか仕事程度(内側のつながりはない)
  • コミュニティではゆるく繋がっているので、今は繋がっているのではないのか
  • Rubyのコミュニティは面白い方々多い
  • 地域Ruby会議に行くと、質問したり自分のことを見直すきっかけになるのでいいかもしれない
  • 普通、ビジネス主体としての会社
  • もう1つは、コミュニティとしての会社
  • 中の人が見えるというのはいい

万葉社長


コードについて言いたいこと

プログラミングはどういう仕事?

良い考えが最良とは限らない(衝突が起きる)

  • クラス名が仕様書番号とか最低すぎる
  • わかりやすい名前
  • 自動テストあるといいよ
  • PHP悪くてRubyがいいという意見は、別れる
  • MVCとオブジェクト指向は?
  • DRYと読みやすさ
  • RDB的に最適解とオブジェクト指向
  • 安全と自由(型など)

そのため、一般的に悪いといわれることが役立つこともある。

他にも・・・

  • すべてを一気に解決することはできない。
  • どの局面で問題を解決をするのが重要
  • 正解なんてものはない。

大事なこと

  • 意思の表明。思ってるだけでは何もできない
  • 考えていることを言語化することが必要
  • たのしくソフトウェア開発ができること
  • 意思をもって選びとること

LT


角谷さん

  • Rubyで仕事しだすと会社とコミュニティと個人のつながりを考えだす
  • WHYから始める

和田さん

  • 6年続くのはすごい
  • 生き生きできるのはレッドじゃなくてサブ
  • オススメ本:はじめの一歩を踏み出そう

これ以外は聞くほうが面白かったのでメモってません。
ごめんなさいm( )m

宿題的なアレ


万葉の中の人にやってること、超面白いし聞きたいんで是非LTやってくださいと勧められました。
なので、機会があればどこかでネタを話たいなーと思います。

# 思ってるだけだとダメなので実際どこかで行動しないといけないですね。

シェルスクリプトで引数を順次処理する

表題のようなことをしたいときってありますよね。

特にオレオレのスクリプトで、引数の数だけ処理を実行したいってときなんかがあると思います。
まーいわゆる引数の回数分、forをグルグル回すだけですね。

以下は、シェルの引数「$@」を変数「arg」に順次格納して、標準入出力に表示してます。

1
2
3
4
5
#!/bin/sh
for arg in $@
do
  echo ${arg}
done

簡単だけど、忘れがちなのでメモしておきました。

iPhoneのカレンダーアプリとGoogleCalendarを同期する

iPhone/iPad購入後、1度しかやらないのでよく忘れます。
そのため、端末を新しくするとやり方を忘れるのでキモだけメモ。

設定アプリ


  • メール/連絡先/カレンダーの設定項目で、Gmailアカウントを登録する
  • 作ったアカウントの設定項目で、カレンダーを「オン」にする
  • その他の項目は、「オフ」でもよい

カレンダーアプリ


  • カレンダーの設定項目で、左下にある同期を押下する
  • Gmail項目が出るので、同期したいものをチェックする

参考


偶にしかやらないと忘れてしまいますね。

3分で認証とか考慮しないWebDavを構築してみる

大したことはないし、そこらへんに構築メモは転がってるので要らないと思うけど・・・

という訳で、一から最低限の機能のみを構築しますという体で進めます。
日本語の文字化け対策にエンコーディングを入れてーみたいなことはしません。

動かすことのみに注力します。

環境


・CentOS6.3 x86_64

Apacheのインストール


以下のコマンドでApacheをインストールします。
このとき、インストールするパッケージはdevelにします。(色々必要なものが一緒に入るので)

1
$sudo yum install httpd-devel

モジュールの確認


WebDavは、Apacheの追加モジュールです。
develパッケージでインストールした場合、自動でインストールされますが念の為に確認します。
以下の2つが、「/etc/httpd/conf/httpd.conf」に記載されているか確認します。

  • LoadModule dav_module modules/mod_dav.so
  • LoadModule dav_fs_module modules/mod_dav_fs.so

記載が無ければ、「/usr/lib/httpd/modules/」に上記モジュールがあるか確認します。
モジュールが存在していれば、追加しましょう。

WebDavの設定


以下の内容で、「/etc/httpd/conf.d/webdav.conf」を作成します。
ACLやBasic認証とかもここで設定できますが、最低限動作なので実施しません。
因みに、ディレクトリに対して細かい設定ができます。

1
2
3
4
5
6
7
8
9
10
#
# This is to permit URL access to WebDav.
#
Alias /webdav/ "/var/www/html/webdav/"
<IfModule mod_dav.c>
    DAVMinTimeout 600
    <Location /webdav>
        DAV On
    </Location>
</IfModule>

WebDav用のディレクトリ作成


WebDavとして共有するためのディレクトリを作成します。

1
$sudo mkdir -p /var/www/html/webdav

ディレクトリをApacheから制御できるように所有者・所有グループを「apache」に変更します。

1
$sudo chown apache:apache /var/www/html/webdav

iptablesの設定


iptablesを未設定のままにすると、iptablesによってアクセスできないので、80番ポートのアクセスを許可するように設定変更します。

1
$sudo emacs /etc/sysconfig/iptables

80番での通信を許可するよう、以下の内容をREJECTの前に追加します。

1
-A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT

iptablesを再起動します。

1
$sudo /etc/init.d/iptables restart

Apacheの起動


以下のコマンドで起動します。

1
$sudo /etc/init.d/httpd start

http://localhost/webdavにアクセス出来れば完了です。

この程度だと、大したことないし知ってれば3分要らないかもw