WindowsからFTPクライアントで(私の場合はエクスプローラで)ディレクトリを削除しようとすると以下のエラーが出た.
550 Create directory operation failed.
本当に原因がわからなくて30分くらい悩んだのだけど,どうも.付きのファイルがFTPで取得できていないのが問題らしい.
そこで/etc/vsftpd/vsftpd.conf内に以下を追記してサービス再起動で解決した.
force_dot_files=YES
マジでハマった.
WindowsからFTPクライアントで(私の場合はエクスプローラで)ディレクトリを削除しようとすると以下のエラーが出た.
550 Create directory operation failed.
本当に原因がわからなくて30分くらい悩んだのだけど,どうも.付きのファイルがFTPで取得できていないのが問題らしい.
そこで/etc/vsftpd/vsftpd.conf内に以下を追記してサービス再起動で解決した.
force_dot_files=YES
マジでハマった.
cacheに乗せたい時やちょっとしたものを作るときには簡単にシリアライズ/デシリアライズできる パッケージがあると便利だ.
gobパッケージを使うと簡単にできるようだ.
rpc向けのパッケージらしい.
他ではencoding/jsonやencoding/xmlだろうか.ここら辺はググればすぐ出ると思う. encoding/binaryも使い道によっては良いと思う.
それでもgobを使ってみたのはgobの方が早いとの記述を何処かで見たからだ.(が,測定はしていない)
使い方は絶対忘れるので作ったサンプルを書いておく.
package main import ( "bytes" "time" "fmt" "encoding/gob" ) // サンプル用の構造体 // 何となくブログ風味 type Entry struct { ID int64 `datastore:"-"` Title string Contents string CreateAt time.Time UpdateAt time.Time DeleteAt time.Time } // シリアライズ用のメソッド // レシーバ(e)の値をシリアライズしてbyte配列にする func (e *Entry) GobEncode() ([]byte, error) { // エンコーダを作る. // io.Writerであれば何でも良いのでここではbytes.Bufferを使う w := new(bytes.Buffer) encoder := gob.NewEncoder(w) // 先頭から順番にエンコードしていく // 必ず先頭から1つずつエンコードを実行していく必要があるらしい if err := encoder.Encode(e.ID); err != nil { return nil, err } if err := encoder.Encode(e.Title); err != nil { return nil, err } if err := encoder.Encode(e.Contents); err != nil { return nil, err } if err := encoder.Encode(e.CreateAt); err != nil { return nil, err } if err := encoder.Encode(e.UpdateAt); err != nil { return nil, err } if err := encoder.Encode(e.DeleteAt); err != nil { return nil, err } return w.Bytes(), nil } // デシリアライズするためのデコーダ // byte配列を渡してレシーバへ値を入れる func (e *Entry) GobDecode(buf []byte) error { // デコーダを作る. // io.Readerであれば何でも良いのでここではbytes.Bufferを使う r := bytes.NewBuffer(buf) decoder := gob.NewDecoder(r) // 先頭から順番にデコードしていく // 必ず先頭から1つずつデコードを実行していく必要があるらしい if err := decoder.Decode(&e.ID); err != nil { return err } if err := decoder.Decode(&e.Title); err != nil { return err } if err := decoder.Decode(&e.Contents); err != nil { return err } if err := decoder.Decode(&e.CreateAt); err != nil { return err } if err := decoder.Decode(&e.UpdateAt); err != nil { return err } if err := decoder.Decode(&e.DeleteAt); err != nil { return err } return nil } func main() { // 記録するデータ e1 := &Entry{ ID: 1, Title: "title", Contents: "contents", CreateAt: time.Now(), UpdateAt: time.Now(), DeleteAt: time.Now(), } // bにシリアライズして入れる b, err := e1.GobEncode() if err != nil { fmt.Println("Error occured.", err) } // デシリアライズするために用意 e2 := &Entry{} // bからe2へデシリアライズ if err = e2.GobDecode(b); err != nil { fmt.Println("Error occured.", err) } // デシリアライズしたものを表示 fmt.Println(e2.ID) fmt.Println(e2.Title) fmt.Println(e2.Contents) fmt.Println(e2.CreateAt) fmt.Println(e2.UpdateAt) fmt.Println(e2.DeleteAt) }
コメントも書いたし,多分思い出せるだろう.
と思ってちょっとググったらちゃんと公式に記載があった.
time package - time - Go Packages
1年1月1日の0時だそうだ.特に驚かない.
ここがこの言語のいいところだと思う. (Rubyにも驚き最小の法則ってあったね)
いちいち判定に上記時刻を使うのは面倒なのでちゃんとIsZero()が用意されてる あたり気が利いている.
こんな感じ.
t := time.Now() if t.IsZero() == false { fmt.Println("初期値じゃないよ") }
というわけでtime型のゼロ値(初期値)判定には(t time)IsZero()を使えばいいそうです.
Ubuntuに変えてもほとんど困りはしないんだけど, 致命的なものの一つにKindleがある.
私は最近ほとんどの書籍をKindleで購入しているので, 技術書なんかはとても困る.
そういうわけでUbuntuにkindleを導入したのだが,ちょっとハマる箇所があったのでメモ.
やっぱりwineを使います.
32bit版の方が良いという記事があったので従っておいた.64bitでも問題ないのかもしれない.
$ sudo dpkg --add-architecture i386 $ sudo add-apt-repository -y ppa:wine/wine-builds $ sudo apt update $ sudo apt install winehq-devel
バージョンは以下の通り
$ wine --version wine-1.9.21
$ wineboot
これは公式からどうぞ
最初はこの工程を行わなかったためどうしてもうまく動かずにハマってしまった.
まず以下のコマンドを実行
$ winecfg
すると新しいウィンドウが現れる.
ここで「Windowsバージョン」をWindows10にすると動作した. 8.1やXPではダメだった.
Ubuntuに久々に戻したところ,キーボード入力がおかしくて1hほど無駄にしてしまった。
ちょっとググると以下のコマンドで対処可能という情報がよく流れてくる.
sudo dpkg-reconfigure keyboard-configuration
実際, 上記でもきちんと入力できるようになる.が,私の環境の場合(Let's Note CF-N9)ログアウトして 再度ログインするとまたキーマップがおかしくなる.
結局下記で対応した. Ibus(mozc)使ってる状況だからだったのかもしれない.
sudo vi /usr/share/ibus/component/mozc.xml
上記の15行目と18行目あたりにlayoutが定義される箇所があるので, ここをjaからjpに変更した.
今のところ問題も特にない.
作りました.
詳細はgithubのREADMEをどうぞ.(酷い英語ですが)
当初は純lispを作ろうと思ったのでpureという名前ですが, tak関数を動かしたいなど欲が出てきたので 純粋でも何でもなくなってます.
GCはありますが, マクロはありません.
(私がマクロをちゃんと理解してないので)
作成時の参考文献は一番下に記載するので興味のある方はご覧ください.
以下は駄文です.
以前から何か言語処理系を作ってみたいなと思っていました.
Brainf*ckはともかく, 作ったことがなかったので.
それとは全く別に私は今27才で, 25,27,32というのは個人的に特別な節目になる年齢じゃないかと感じていました.
SIerにいると年齢と共にプログラミングする機会が減っていくのでなんとなく腕試ししたくなる事がよくあります.
「プログラマを名乗るならここら辺で小さくてバグだらけでも良いので言語処理系を作っておきたいな」という事で着手してみました.
とはいえ何から始めたらよいのかという事でとりあえずググって色々調べてみました.
が, イマイチピンときません.
ここら辺で割と心が折れます.
とりあえず何かを真似したいという事でOSSやコードの載っている本を買って写経する事を試みました.
lispとかなら割とサンプルも多かったので調べるといくつか出てきます.
が, これもまたイマイチピンときません.
作ってる感がないというか, あんまり頭に入ってこなかったんですよね.
わかったよーな, わからんよーな.
弱ったなーという事で気分転換にrebuild.fmを聞く事にしました. この時まで聞いたことなかったんですが, 以前Cコンパイラ作る記事を見たことがあるruiさんが出るという事でタイミング的にもいいし聞いてみようかなと.
この回だったかな?
(そういえばこの後Matzさんも出てますね.たまたまですが時期がよかった)
トークの中で東大のCPU実験の話がありましたが,その文脈でruiさんから出た
「やってみればいいじゃないですか?」的な一言がとても心に残りました.
細かい文脈などは忘れてしまったんですが,それだけが心に残っています.
「まぁ,そりゃそうだな」という事で参考文献ばかり漁らずにやってみることにしました.
とりあえず小さく始めることがベストという事で極小のlisp定義を漁ります.
するとwikipediaで以下を見つけました.
「あぁ,こいつならなんとかなるかも」という事でターゲットをこれに絞ります.
Lispならまぁ大体
という3工程だろうと考えました.
あとはデータ構造ですが,これはLispなら大変わかりやすいので(アトムとペアしかない)何となくこの2つを作ればうまくいくだろうということで着手します.
これで8末くらいから初めて9月末くらいでReadして何かしらEvalしてPrintというところまでこぎつけました.(car, cdrとかは動いた)
が,変数スコープなどを足そうとすると一気に難しくなります.
このあたりで既存コードで作り続けるのは辛いなという事で一度挫折しました.
ならもう作り直せばいいわ.という事でゼロからもう一度作り始める事にしました.
1度作ってるだけあってリトライは割とうまくいき, 9月末から始めて10月中頃には終える事が出来ました.日数だと8日かな.
勉強になったというよりはかなり面白かったというのが正直なところです.
勉強がどうとかいうと聞こえはいいですが,結局面白いのが一番だというのが個人的な結論でしょうか.
あとはちょっとでもやり続ける事も割と大事でした.
子供もいるのでなかなか時間が作れないのですが, 仕事の休憩中とか5分でも,その5分で1機能作れたりしましたし.
あとはあのタイミングでrebuild.fmを聞かなければおそらく挫折していたと思います. ruiさんとmiyagawaさんにはここでひっそりと感謝を.
参考サイトが多すぎるので最早覚えてないのですがブラウザのブックマークに残っているものを並べておきます.
Rubyソースコード完全解説 - 第5章 ガ-ベージコレクション
パソコン初心者みたいだけど、知らなかったのでメモっとく.
Windowsのコマンドプロンプトではclipコマンドというものがあって、クリップボードにコマンド結果などをコピーできる.
date /T | clip
貼り付け結果:
2016/10/15
echoでちょっとしたものを出したり.
echo "hello" | clip
貼り付け結果:
"hello"
テキストファイルの内容もコピペが簡単
clip < sample.txt
貼り付け結果:
テキストの中身だよ
こりゃ地味に便利