2020/08,江端さんの技術メモ

  1. まずは、MSYS2をメンテナンス(2年近く放置していたから)
$ pacman -Syu

を、ターミナルを何度も立ち直し続けてパッケージの更新を繰返す。

$ pacman -S base-devel
$ pacman -S msys2-devel
$ pacman -S mingw-w64-x86_64-toolchain
$ pacman -S mingw-w64-x86_64-gnutls
$ pacman -S mingw-w64-x86_64-ruby
$ pacman -S nano      #(簡易エディター)
$ pacman -S make      #(make をインストール ※重要※)
$ pacman -S openssh   #(openssh をインストール)
$ pacman -S git       #(Git をインストール)
$ pacman -S ruby      #(Ruby をインストール)
$ pacman -S ruby-docs #(Rubyドキュメント をインストール)
$ pacman -S p7zip     #(7z をインストール)
$ pacman -S mingw-w64-x86_64-ag  #(ag 高速検索コマンドをインストール)

2. パッケージのインストールとアンインストール

sudo pacman -S [パッケージ名]
sudo pacman -R [パッケージ名]

3. Windows10の環境をMSYS2に引きつぐ方法

2020/08,江端さんの技術メモ



go func() { defer close(done) for { _, message, err := c.ReadMessage() if err != nil { log.Println("read:", err) return } log.Printf("recv: %s", message) } }() ticker := time.NewTicker(time.Second) defer ticker.Stop() for { select { case <-done: return case t := <-ticker.C: err := c.WriteMessage(websocket.TextMessage, []byte(t.String())) if err != nil {

go func()で、defer close(done)が効いてくるまで、 case <-done:はロックされて、デッドロックになるじゃないか? と、ずっと考えて訳が分からなくなってきたところで、Go言語でチャネルとselect というページに、

チャネルに値が入っていない場合、受信はブロックする。ブロックせずに処理を行いたい場合は select を使う。

そんなSwitchの使いかた、あるかーーーー! と、叫びそうになりました(私の2時間を返せ)

2020/08,江端さんの忘備録

「やはり俺の青春ラブコメは間違っている完」の第8話の視聴後感想になります。

This is my impression after watching episode 8 of "My Youth Romantic Comedy is Wrong,As I Expected -- Final"

実は、今回のエピソードが、これまでで、一番私にショックを与えています。

Actually, this episode has shocked me the most, so far.

-----

私、ティーンエイジャの頃、生徒会役員とか、文化祭実行委員などもやっていました。

When I was a teenager, I was a student council member and a member of the school festival committee.

各種の企画を通す為であれば、生徒会会長や、実行委員長の職権を利用して、裏側で色々なことを画策していました。

In order to get the various projects passed, I was planning many things behind the scenes, using the authority of the student council president and the chairman of the executive committee.

企画を通す為に、正規のルートを通さない「根回し」や「裏工作」もしてきたと思います。

I think I've done some "diggint route root" and "behind-the-scenes maneuvering" that didn't go through regular channels if it was to get the project through.

で、まあ、この私の性格(狭量、浅学、卑怯)は、今に至るまで直っていませんが。

And, well, this character of mine (narrow, shallow, and cowardly) has not been fixed to this day.

ちなみに、私の価値観の根幹は「本物」でもなく「正道」でもなく「完了」です ―― が、まあ、その話はいずれまた。

By the way, my core values are not "real" or "righteous" but "complete" -- but, well, I'll talk about that soon.

-----

今回の第8話を視聴して、私が、今、ゾッとしていることは、私の、ティーンエイジャの頃、いい気になってやっていた「根回し」や「裏工作」を、

After watching this episode 8, about "diggint route root" and "behind-the-scenes maneuvering" I had done when I was a teenager,

当時、私を監修している大人たちからは、

At the time, the adults supervising me had

―― 丸見え

"seen them all"

だったのではないか、ということです。

I doubt they had thought

■『あいつ(江端)が何をやっているのか分かっているが、ほっとけば、企画をそこそこのレベルに持ち上げて、完了させるだろう』

"I know what he (Ebata) is doing, but if we leave him alone, he'll lift the project to that level and get it done."

■『本当に、ヤバくなれば、あいつ(江端)1人を潰せば、企画も潰せる』

"If things get really bad, we can destroy the project if we destroy him alone"

と思われて、

私の「根回し」や「裏工作」は、看過され続けていたのではないか?

Didn't my "diggint route root" and "behind-the-scenes maneuvering" continue to be overlooked?

私はいい気になって、「完了」できたことに、一人悦に入っていたのではないか?

Didn't I feel good about it, and I was alone in my euphoria at being able to "complete" it?

今、思い返せば、そういう例もいくつかあったような気がします。

Now that I think about it, I think there were a few examples of that.

-----

私のティーンエイジャとは、

My teenagers may bave been just a

『大人の掌の上で踊らされ続けて、それすら気が付つかなかった"頭の悪い子ども"』

"stupid child who has been dancing on the hands of adults and doesn't even know it"

に過ぎなかったのかもしれない。

-----

嫌なことに気が付いてしまったなぁ ―― と、番組の視聴後に思いました。

After watching the episode 8, "I just found something I didn't like".

2020/08,江端さんの技術メモ

https://github.com/gorilla/websocket/tree/master/examples/echo

この"server.go"は、client.goからの通信だけではなく、ブラウザの画面も提供します(スゴい!)。

というか、Goプログラムの中に、html書けるなんて知らんかった。

 
// server.go

// Copyright 2015 The Gorilla WebSocket Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

//go:build ignore
// +build ignore

package main

import (
	"flag"
	"html/template"
	"log"
	"net/http"

	"github.com/gorilla/websocket"
)

var addr = flag.String("addr", "localhost:8080", "http service address")

var upgrader = websocket.Upgrader{} // use default options

func echo(w http.ResponseWriter, r *http.Request) {
	c, err := upgrader.Upgrade(w, r, nil)
	if err != nil {
		log.Print("upgrade:", err)
		return
	}
	defer c.Close()
	for {
		mt, message, err := c.ReadMessage()
		if err != nil {
			log.Println("read:", err)
			break
		}
		log.Printf("recv: %s", message)
		err = c.WriteMessage(mt, message)
		if err != nil {
			log.Println("write:", err)
			break
		}
	}
}

func home(w http.ResponseWriter, r *http.Request) {
	homeTemplate.Execute(w, "ws://"+r.Host+"/echo")
}

func main() {
	flag.Parse()
	log.SetFlags(0)
	http.HandleFunc("/echo", echo)
	http.HandleFunc("/", home)
	log.Fatal(http.ListenAndServe(*addr, nil))
}

var homeTemplate = template.Must(template.New("").Parse(`
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script>  
window.addEventListener("load", function(evt) {

    var output = document.getElementById("output");
    var input = document.getElementById("input");
    var ws;

    var print = function(message) {
        var d = document.createElement("div");
        d.textContent = message;
        output.appendChild(d);
        output.scroll(0, output.scrollHeight);
    };

    document.getElementById("open").onclick = function(evt) {
        if (ws) {
            return false;
        }
        ws = new WebSocket("{{.}}");
        ws.onopen = function(evt) {
            print("OPEN");
        }
        ws.onclose = function(evt) {
            print("CLOSE");
            ws = null;
        }
        ws.onmessage = function(evt) {
            print("RESPONSE: " + evt.data);
        }
        ws.onerror = function(evt) {
            print("ERROR: " + evt.data);
        }
        return false;
    };

    document.getElementById("send").onclick = function(evt) {
        if (!ws) {
            return false;
        }
        print("SEND: " + input.value);
        ws.send(input.value);
        return false;
    };

    document.getElementById("close").onclick = function(evt) {
        if (!ws) {
            return false;
        }
        ws.close();
        return false;
    };

});
</script>
</head>
<body>
<table>
<tr><td valign="top" width="50%">
<p>Click "Open" to create a connection to the server, 
"Send" to send a message to the server and "Close" to close the connection. 
You can change the message and send multiple times.
<p>
<form>
<button id="open">Open</button>
<button id="close">Close</button>
<p><input id="input" type="text" value="Hello world!">
<button id="send">Send</button>
</form>
</td><td valign="top" width="50%">
<div id="output" style="max-height: 70vh;overflow-y: scroll;"></div>
</td></tr></table>
</body>
</html>
`))
// client.go

// Copyright 2015 The Gorilla WebSocket Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

//go:build ignore
// +build ignore

package main

import (
	"flag"
	"log"
	"net/url"
	"os"
	"os/signal"
	"time"

	"github.com/gorilla/websocket"
)

var addr = flag.String("addr", "localhost:8080", "http service address")

func main() {
	flag.Parse()
	log.SetFlags(0)

	interrupt := make(chan os.Signal, 1)
	signal.Notify(interrupt, os.Interrupt)

	u := url.URL{Scheme: "ws", Host: *addr, Path: "/echo"}
	log.Printf("connecting to %s", u.String())

	c, _, err := websocket.DefaultDialer.Dial(u.String(), nil)
	if err != nil {
		log.Fatal("dial:", err)
	}
	defer c.Close()

	done := make(chan struct{})

	go func() {
		defer close(done)
		for {
			_, message, err := c.ReadMessage()
			if err != nil {
				log.Println("read:", err)
				return
			}
			log.Printf("recv: %s", message)
		}
	}()

	ticker := time.NewTicker(time.Second)
	defer ticker.Stop()

	for {
		select {
		case <-done:
			return
		case t := <-ticker.C:
			err := c.WriteMessage(websocket.TextMessage, []byte(t.String()))
			if err != nil {
				log.Println("write:", err)
				return
			}
		case <-interrupt:
			log.Println("interrupt")

			// Cleanly close the connection by sending a close message and then
			// waiting (with timeout) for the server to close the connection.
			err := c.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, ""))
			if err != nil {
				log.Println("write close:", err)
				return
			}
			select {
			case <-done:
			case <-time.After(time.Second):
			}
			return
		}
	}
}

2020/08,江端さんの忘備録

私は、一人で仕事をするのが好きです。

I like to work alone.

ですから、コラムの執筆は、私の性癖にあっているようです。

So, writing the column seems to be in my nature.

しかし、現在のコラムの執筆に関しては ――

But as for writing the current column,

編集担当者のMさん、量子コンピュータの監修者のTさん、そして、いわゆる「無礼な後輩」の御三方の支援なくしては、成立しません。

It wouldn't be possible without the support of Ms. M. as the editor, Mr. T as the supervisor of quantum computer, and the three so-called "rude junior".

ところが、Mさんを除いては、無償でご協力頂いている(クレジットの表示もご辞退されています)ので、大変心苦しいと思っています。

However, with the exception of Mr. M., I am very distressed by the fact that they has cooperated with me free of charge (and have declined to show credit).

だから、監修や査読のお願いに対して、締切等を申し上げられない立場です。

So it is hard for me ask them for deadline about supervision and peer review

-----

今回、「無礼な後輩」に対して、3回ほど、立て続けにフォローメールをしたところ、

This time, I sent three follow-up emails in a row to the "rude junior, and the call came back and

開口一番、

His first words are

『江端さん、嫌がらせですか』

"Ebata-san, are you harassing me?"

と、電話がかかってきました。

-----

そんな、ボランティアでご協力頂いている恩人に、事もあろうに『嫌がらせ』なんて、そんな不遜な気持ち ――

I don't like the idea of "harassment" for a benefactor who has volunteered to help me. Such irreverence is

「半分くらい」

"only the half".

しか、ありません。

2020/08,江端さんの忘備録

最近、睡眠不足気味で、ちょくちょく仮眠を取るようにしています。

Lately, I've been sleep-deprived and I've been trying to take a nap every so often.

私の体の中にある「乾電池」は、とても性能のよいやつで、

The "dry cell" in my body is a very good performing one.

「10分間の仮眠で、5時間連続稼動」

"I'll take a 10-minute nap and run for five hours straight"

できます、

これ、一見、良さそうに見えますが、「性(たち)の悪い不眠症の原因」となっています。

This may seem like a good one, but it is the "cause of our bad insomnia".

-----

昨日も、タイマーに「10分間」セットして、横になりました。

Yesterday, I set the timer for "10 minutes" and laid down.

残り8分34秒のところで目が覚めました。

I woke up with 8:34 to go.

2分弱しか仮眠が取れていないのに、その割には、体調がスッキリしています ―― 最近、経験したことがないくらい。

I've only been able to take a nap for less than two minutes. However I was feeling better than I'd have experienced in recent years.

変だなーと思って、時計を確認したら、

I thought it was odd, so I checked my watch.

セットしたタイマーの時間は、"10分間"ではなく、"10時間"でした。

The timer was set for "10 hours", not "10 minutes".