golangセットアップしてみた

Goインストール

        • -

まずchocolatery入れてから。 (https://chocolatey.org/)
choco経由でインストール。

choco install golang

>go version
go version go1.2.2 windows/amd64

Vim環境構築

        • -

Big Sky :: Vimを使ったGo言語開発手法
http://mattn.kaoriya.net/software/vim/20130531000559.htm

GOPATH設定してnsf/gocode取得。
http://qiita.com/yuku_t/items/c7ab1b1519825cc2c06f

>go get github.com/nsf/gocode

Big Sky :: quickrun.vimでgoのコーディング効率が数倍になった件
http://mattn.kaoriya.net/software/lang/go/20091113024906.htm

これうまく動かなかった。
手でRunしてHello Worldした。
満足。

>go run trial.go
hello world

gitメモ

## git初期設定
'''bash
git config --global user.name 'qnzm'
git config --global user.email 'qnzm@gmail.com'
git config --global color.ui auto
git config --global core.editor vim
'''

## ブランチ
### ローカルブランチ
git branch であらわれるブランチ。
/refs/heads/

### リモート追跡ブランチ(remote tracking branch)
他のリポジトリで歴史が作られる家庭を追跡することのみが目的のブランチ。
コミットすることができない。
/refs/remotes/

すべてのブランチは、 git branch -a で確認できる。
''' bash
% git branch -a
* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/master
'''

''' bash
% ls -alR .git
.git/refs/heads:
total 8
drwxr-xr-x  3 userm  staff  102  5  5 13:10 .
drwxr-xr-x  5 userm  staff  170  5  5 13:09 ..
-rw-r--r--  1 userm  staff   41  5  5 13:10 master
〜
.git/refs/remotes/origin:
total 16
drwxr-xr-x  4 userm  staff  136  5  5 13:10 .
drwxr-xr-x  3 userm  staff  102  5  5 13:09 ..
-rw-r--r--  1 userm  staff   32  5  5 13:09 HEAD
-rw-r--r--  1 userm  staff   41  5  5 13:10 master

% cat .git/refs/heads/master         
942e60094606c59b90a21e26cd087830180e83c0

% cat .git/refs/remotes/origin/HEAD 
ref: refs/remotes/origin/master

% cat .git/refs/remotes/origin/master
942e60094606c59b90a21e26cd087830180e83c0
'''

### git pull
1. git fetch にて、リモート追跡ブランチを更新
2. git merge にて、指定されたリポジトリのブランチをマージ

### .git/config
cloneしてきたら、configには以下の記述が。

[remote "origin"]
	fetch = +refs/heads/*:refs/remotes/origin/*
	url = /Users/userm/sketch/app.git
[branch "master"]
	remote = origin
	merge = refs/heads/master

### git fetch
fetchの部分は、コマンドパラメータ。
一番長い記述だと、

git fetch /Users/userm/sketch/app.git '+refs/heads/*:refs/remotes/origin/*'
第一引数はそのままでも省略できる。
第二引数がリモートブランチの更新を表す。
この第に引数が、configには定義されている。

#### 引数左辺
+refs/heads/*
当該リポジトリから、このパターンにマッチするリファレンスを取ってこい
→ リポジトリのローカルブランチすべて取ってこい

#### 引数右辺
refs/remotes/origin/*
とってきたリファンレンスを、手元のこの階層にしまえ 
→ /refs/remotes/origin/master にコピーする。 

gitのブランチに慣れる

subversionと違い、gitはブランチ/マージを積極的に利用することが推奨されています。
簡単なサンプルシナリオで、ブランチを使った開発に慣れたいと思います。

## シナリオ

### 環境

一複数箇所をシュミレーションするため、二カ所のワーキングスペースを持つ。

### 作業手順

1. 下準備(app.gitをcloneしてapp1・app2を作成)

2. メンバ1: ブランチfirstを作成
3. メンバ1: a.txtを編集してcommit
4. メンバ1: firstをmasterにmerge、push

5. メンバ2: ブランチsecondを作成
6. メンバ2: a.txtを編集してcommit
7. メンバ2: secondをmasterにmerge、a.txtのコンフリクトを解決し、commit、push

## 作業

### 1. 下準備(app.gitをcloneしてapp1・app2を作成)
/var/src% mkdir app.git
/var/src% cd app.git
/var/src/app.git% git init --bare --share
Initialized empty shared Git repository in /private/var/src/app.git/
/var/src/app.git% git config --global user.name 'qnzm'
/var/src/app.git% git config --global user.email 'qnzm@gmail.com'
/var/src/app.git% git config --global core.editor vim            
/var/src/app.git% git config --global color.ui auto  
/var/src/app.git% cd ..
/var/src% git clone /var/src/app.git app1
Cloning into app1...
done.
warning: You appear to have cloned an empty repository.
/var/src% git clone /var/src/app.git app2
Cloning into app2...
done.
warning: You appear to have cloned an empty repository.

/var/src/app1% echo aaaaa >a.txt     
/var/src/app1% git add -A    
/var/src/app1% git commit -m "first
/var/src/app1% git push origin master
Counting objects: 3, done.
Writing objects: 100% (3/3), 202 bytes, done.
Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
To /var/src/app.git
 * [new branch]      master -> master

/var/src/app1% cd ..     
/var/src% git clone /var/src/app.git app2
Cloning into app2...
done.
### 2. メンバ1: ブランチfirstを作成
/var/src% cd app1
/var/src/app1% git checkout -b first
Switched to a new branch 'first'
/var/src/app1% git branch
* first
  master
### 3. メンバ1: a.txtを編集してcommit
/var/src/app1% echo bbbbbccccc >>a.txt 
/var/src/app1% cat a.txt 
aaaaa
bbbbbccccc
/var/src/app1% git add -A
/var/src/app1% git commit -m "add bbbbbccccc"
[first efd1a02] add bbbbbccccc
 1 files changed, 1 insertions(+), 0 deletions(-)
### 4. メンバ1: firstをmasterにmerge、push
/var/src/app1% git checkout master
Switched to branch 'master'
/var/src/app1% git branch 
  first
* master
/var/src/app1% git merge first
Updating d149748..efd1a02
Fast-forward
 a.txt |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)
### 5. メンバ2: ブランチsecondを作成
/var/src/app1% cd ../app2
/var/src/app2% git checkout -b second
Switched to a new branch 'second'
### 6. メンバ2: a.txtを編集しcommit
/var/src/app2% cat a.txt 
aaaaa
/var/src/app2% echo ddddd >>a.txt 
/var/src/app2% sed s/a/e/g a.txt
eeeee
ddddd
/var/src/app2% git add -A
/var/src/app2% git commit -m "second"
[second e10a7cd] second
 1 files changed, 1 insertions(+), 0 deletions(-)
### 7. メンバ2: secondをmasterにmerge、a.txtのコンフリクトを解決、push
/var/src/app2% git checkout master 
Switched to branch 'master'
/var/src/app2% git pull        
remote: Counting objects: 5, done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From /var/src/app
   d149748..efd1a02  master     -> origin/master
Updating d149748..efd1a02
Fast-forward
 a.txt |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)
/var/src/app2% git merge second
Auto-merging a.txt
CONFLICT (content): Merge conflict in a.txt
Automatic merge failed; fix conflicts and then commit the result.
/var/src/app2% cat a.txt 
aaaaa
<<<<<<< HEAD
bbbbbccccc
=======
ddddd
>>>>>>> second

a.txtを編集。

aaaaa
bbbbbccccc
ddddd

commit、push。

/var/src/app2% git commit -a -m "コンフリクトを解決"
[master 254ed11] コンフリクトを解決
/var/src/app2% git push
Counting objects: 10, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (6/6), 507 bytes, done.
Total 6 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (6/6), done.
To /var/src/app.git
   efd1a02..254ed11  master -> master

文章から名詞を抽出して出現回数を数える

こちらのエントリを参考にさせていただいて、文章から名詞を抽出して出現回数を数えるスクリプトを作成しました。

Yahoo開発者登録して、AppID取得

Yahooアカウント作成
アプリケーションIDの登録

サンプルのappidを、登録時に取得できたアプリケーションIDに置き換える。

BeautifulSoupインストール

この解析にはBeautifulSoupが必要。
実行マシンであるWindowsマシンだとeasy_installによる適用がうまくいかなかったので、サイトからアーカイブ取得して展開、setup.pyを実行する形をとった。

>setup.py install
running install
running build
running build_py
creating build
creating build\lib
copying BeautifulSoup.py -> build\lib
copying BeautifulSoupTests.py -> build\lib
running install_lib
copying build\lib\BeautifulSoup.py -> C:\Python25\Lib\site-packages
copying build\lib\BeautifulSoupTests.py -> C:\Python25\Lib\site-packages
byte-compiling C:\Python25\Lib\site-packages\BeautifulSoup.py to BeautifulSoup.pyc
byte-compiling C:\Python25\Lib\site-packages\BeautifulSoupTests.py to BeautifulSoupTests.pyc
running install_egg_info
Writing C:\Python25\Lib\site-packages\BeautifulSoup-3.2.0-py2.5.egg-info

ソースと実行結果

名詞出現回数数え上げサンプル:yomi.py
# -*- coding: utf_8 -*-

from urllib import urlopen, quote_plus, urlencode
from BeautifulSoup import BeautifulSoup
import urllib
import codecs

#pageurl='http://api.jlp.yahoo.co.jp/MAService/V1/parse'
pageurl='http://jlp.yahooapis.jp/MAService/V1/parse'
appid='set your appid'

def countword(text,dict={},appid=appid,results='ma',filter=''):
    text=text.encode('utf-8')
    postdata= {
            'appid': appid,
            'sentence' : text,
            'results' : results,
            'response' : 'surface,pos',
            'filter' : filter}

    params=urllib.urlencode(postdata)
    f = urllib.urlopen(pageurl, params)
    soup = BeautifulSoup(f.read())
    readings=soup('surface')
    for yomi in readings :
        pos = yomi.nextSibling.string
        if pos == u'名詞':
            s = yomi.string
            if not dict.has_key(s):
                dict[s] = 0
            dict[s] = dict[s] + 1
    return dict

if __name__ == '__main__':
    f=codecs.open('wordlist.txt','r','shift_jis')
    dict = {}
    for line in f.readlines() :
        word=line.rstrip()
        dict=countword(word, dict)
    for k in dict.keys():
        print (k+'->'+str(dict[k])).encode('shift_jis')
wordlist.txt
わが輩は猫である
名前はまだない
寿限無寿限無五劫の擦り切れ
海砂利水魚
長靴を履いた猫
海千山千
実行結果
>yomi.py
水魚->1
寿限無->2
名前->1
わが輩->1
猫->2
砂利->1
海千山千->1
長靴->1
五->1
海->1
劫->1
擦り切れ->1

参考にしました。

.htaccessでmod_rewriteを使ったときのメモ

.htaccessmod_rewriteを使ったときに、しばらくうまく動かなかった。
結局のところ幾点かの勘違いのせいだったのだけれど、これら分かりにくかった点をメモとして残しておく。
(触り始めたばかりなので、下記認識にも誤りがあるかもしれない…)

prefixの部分が取り除かれた状態でルールが適用される

ファイル構成

/somepath/
┗ccc/index.html
┗eee/index.html
.htaccess

.htaccess

RewriteEngine on
RewriteBase /ccc

RewriteRule ^/aaa$ index.html [L]
RewriteRule ^/bbb$ /eee/index.html [L]

このとき、

  • GET /aaa
    1. /somepath/aaa (物理パス)
    2. /aaa
    3. index.html (mod_rewriteによる書き換え)
    4. /ccc/index.html (RewriteBaseによる補完)
    5. /somepath/ccc/index.html
  • GET /bbb
    1. /somepath/aaa (物理パス)
    2. /bbb
    3. /eee/index.html (mod_rewriteによる書き換え)
    4. (書き換えが"/"はじまりなので、RewriteBaseによる補完は走らない)
    5. /somepath/eee/index.html

RewriteCondは直後のRewriteRule一つに作用する

RewriteEngine on
RewriteBase /ccc
RewriteCond %{HTTP_USER_AGENT} iPhone [NC]
RewriteRule ^/hhh$                                                       index.html                    [R]
RewriteRule ^/iii?$                                                      /eee/index.html                 [R]

UserAgentでiPhoneからのアクセスかどうかを見分けるRewriteCondだが、これが作用するのは"^/hhh$→/ccc/index.html"のルールのみ。

オプション[R]と[L]

  • [L]
    • 最後の書き換えとなり、以降のルールは無視される。
    • この書き換え後も、ブラウザ上のURLはそのまま。
  • [R]
    • リダイレクト。
    • この書き換え後は、ブラウザ上のURLも書き換え後のものとなる。

.htaccessでのmod_rewriteは使わないほうがいい

httpd.confに書くのと違い、リクエスト毎に処理が走るためパフォーマンスに影響がでる。

WCFとSOAP・REST

WCF勉強中につき、メモ書きです。
インサイドWindows Communication Foundation』を読みながら、関連を調べてという形で進めてます。



インサイドWindows Communication Foundation』によれば、WCFは当初SOAP/WS-*を前提としている部分が大きかった様子。JSONなどの台頭自体はWCF開発チームにとって予想外だったのでは?という記載があった。JSONというか、RESTアーキテクチャスタイル。

WCFSOAP, REST, POXをサポートしています。ただし、現在のWCF APIのほとんどは、SOAPメッセージ構造にのみ対応しています。
将来的には、JSONなどのほかのメッセージング構造にも対応するように拡張される予定です。
インサイドWindows Communication Foundation/p.28』

※POXは「Plain Old XML」の略。SOAPWSDLとの対比で利用される。

POX メッセージでは重要なプロトコル情報の搬送に SOAP ヘッダーを使用しないため、POX クライアントおよびサービスでは、メッセージの送受信に使用される、基になる HTTP 要求の情報を操作する必要が生じる場合がよく起こります。
『POX アプリケーションとの相互運用性 http://msdn.microsoft.com/ja-jp/library/aa738456.aspx

その主な理由は 2 つあります。1 つは、REST には、多くの場合に RPC テクノロジより優れている重要な機能や利点があるということです。もう 1 つは、マイクロソフトが固有の実装の多くを SOAP などの RPC テクノロジから REST に移行する方向に向かっているということです。したがって、REST を使用してシステムを構築することに納得できず、その気にならない場合でも、マイクロソフトをはじめとするベンダが多くのフレームワークやテクノロジを REST に移行するようになると、REST の操作方法を習得せざるを得ません。
『REST および WCF サービスの概要 http://msdn.microsoft.com/ja-jp/magazine/dd315413.aspx

SOAPはRPCだ」という言及がある。『Webを支える技術』でも、「SOAPはRPCをHTTP上で走らせるための技術だ』といった旨の言及があったことを見るに、この感覚は共通認識としてある様子。

RPC/分散オブジェクトグループの動きの中で最も基本的なプロトコルSOAPです。SOAPは、HTTPをアプリケーションプロトコルではなくトランスポートプロトコルとして扱い、HTTPの上で独自のメッセージを転送します。SOAPMicrosoftW3Cに提案し、IBMやそのほかのベンダーを巻き込んで標準化が始まりました。
『Webを支える技術/p.021』

そういえば『インサイドWindows Communication Foundation』の中で、TCP・HTTP・名前つきパイプをまとめてトランスポート層みたいな言及があって「?」って思ったのだった。本読み進めるとき、少し気をつけてみておこう。
あと、MS自体がSOAPからRESTに向かってるという言及が気になる。

プログラミング モデルとインフラストラクチャの構築が必要な部分は、.NET Framework 3.5 の System.ServiceModel.Web アセンブリWCF に追加されました。.NET Framework 3.5 SP1 では、いくつかの細かい点も改善されています。
『REST および WCF サービスの概要 http://msdn.microsoft.com/ja-jp/magazine/dd315413.aspx

System.ServiceModel.Web名前空間は、REST用らしい。そしてWebGetAttribute と WebInvokeAttributeが要、とも。

ルーティングの違い

メッセージのルーティングが、SOAPとRESTで異なる。
既定のメッセージルーティング(=ディスパッチ)はアクション概念に基づいており、SOAP仕様のActionヘッダを既定で利用するため、SOAPと密結合している。
RESTインフラストラクチャ利用の場合、これがURIおよびHTTP動詞に基づくルーティングに置き換えられる。(→ WebHttpDispatchOperationSelector )

WebGetAttribute は、メソッドが HTTP GET 要求に応答する必要があることをディスパッチャに通知します。WebInvokeAttribute は既定で HTTP POST にマップされますが、WebInvokeAttribute.Method プロパティを設定して、他の HTTP 動詞 (PUT および DELETE の 2 つが最も一般的) をサポートすることができます。既定では、URI は、エンドポイントのベース URI に追加されたメソッドの名前によって指定されます。
メソッド名は動詞を表しているので、この処理は RESTful とは言えません。URI として公開するには、名詞が適しています。そのため、WCF の REST プログラミング モデルでは、WebGetAttribute または WebInvokeAttribute の UriTemplate プロパティで設定可能なテンプレートを使用して、各メソッドの URI をカスタマイズできます。
『REST および WCF サービスの概要 http://msdn.microsoft.com/ja-jp/magazine/dd315413.aspx

そしてメソッドとURL・HTTP動詞のマッピングにWebGetAttribute・WebInvokeAttributeが用いられる。

More On REST

SOAP、REST、およびその他
http://msdn.microsoft.com/ja-jp/magazine/dd942839.aspx#MtViewDropDownText

REST or SOAP

RESTはクライアント/サーバアーキテクチャスタイルの派生。SOAPは二者間のデータ通信プロトコル仕様。
SOAPはプロキシ生成を必要とし、RESTはHTTPセマンティクスに依存。

simple != easy

I often say that REST is simple, but simple doesn't always mean easy. SOAP is easy (because of WSDL), but easy doesn't always mean simple.
SOAP、REST、およびその他 http://msdn.microsoft.com/ja-jp/magazine/dd942839.aspx#MtViewDropDownText

hope that after you read this column, you'll think that the answer to "Which is better, REST or SOAP?" is "It depends."

当エントリは、「RESTもSOAPも一長一短」という形で締められている。

WADL(Web Application Description Language)

https://wadl.dev.java.net/wadl20061109.pdf