あるプログラマの日記

プログラマのメモ、出来事、考えたこと、勉強とかの雑記

Go で少し混乱したこと

Go言語で時間を扱う time.Time のゼロ値で、勘違いしていたこと。

1970-01-01 09:00:00 はUnixタイムが0なのでゼロ値だと思っていましたが 違いました。
location "Asia/Tokyo" の time.Time のゼロ値は

local, _ := time.LoadLocation("Asia/Tokyo")
ztim := time.Time{}.In(local)
fmt.Printf("%v %v %v\n", ztim, ztim.Unix(), ztim.IsZero())
0001-01-01 09:18:59 +0918 LMT -62135596800 true

でした。

local, _ := time.LoadLocation("Asia/Tokyo")
tim := time.Unix(0, 0).In(local)
fmt.Printf("%v %v %v %v\n", tim, tim.Unix(), tim.IsZero())
1970-01-01 09:00:00 +0900 JST 0 false

なお、time.LoadLocation("Asia/Tokyo")は
1888-01-01 00:00 より前の時間だと、Location は Tokyo の LMT(Local Mean Time)
になるので、ゼロ値は LMTになります。

ゼロ値も JST (日本標準時)にしたい場合は、Locationをtime.FixedZone("JST", 9*60*60)にすればできます。

jst := time.FixedZone("JST", 9*60*60)
jtim := time.Time{}.In(jst)
fmt.Printf("%v %v %v %v\n", jtim, jtim.Unix(), jtim.IsZero())
0001-01-01 09:00:00 +0900 JST -62135596800 true

1888-01-01 00:00以降の時間はtime.LoadLocation("Asia/Tokyo")の Location は JST です。

local, _ := time.LoadLocation("Asia/Tokyo")
ztim := time.Date(1888, 1, 1, 0, 0, 0, 0, local)
fmt.Printf("%v\n", ztim,)
1888-01-01 00:00:00 +0900 JST

JST日本標準時)は1888年1月1日から使用されるようになりました。
それより前は東京の地方平時(LTM)が使われています。

Goをwindows 上で動かすとエラーが発生

GoのプログラムをWindows 環境で動作させたときに
time.LoadLoaction から error が返ってきた。
外部依存(lib/time/zoneinfo.zip)している。

    local, err := time.LoadLocation("Asia/Tokyo")

JSTなので、エラーチェックで限定的な対策を行った。

    if err != nil {
        local = time.FixedZone("JST", 9*60*60)
    }
    // .. snip ..
    time.Date(year, month, day, hour, minute, second, 0, local)

javascript のオブジェクトの空の判定

忘れるので javascript のオブジェクトの空判定({})をメモ

初期値(空オブジェクト)から値がセットされたかをチェックしたいとき

    let data = {};
    // -- snip --

JSONデータをちゃんと取得できてない場合とかのチェックで使用

    // -- snip --
    if (!Object.keys(data).length) {
        console.log("empty data")
    } 

Go言語でハマったこと

昨年末ごろからGo言語を使って開発をするようになってだいぶん快適になってきたのですが、最近ちょっとハマってしまった事を書き留めておきます。

開発は Go + echo + React + webpack + babel です。

フロントエンドから、JSONデータをGoの構造体の配列として echo の Bind で、受け取っていました。
配列データとは別でもう一つ新規に情報を追加することになり、追加したとたんにデータが取得できなくなったのです。
Bindでは error は発生してないのに、取得したデータが空文字列になるようになり配列の各要素(ポインタ)は nil です。

Go構造体の定義とかフロント側の渡し方の問題ではないかと何度も見直したが、おかしくはなさそうでいろいろ試したのですが、原因がなかなかわからなったのです。
こういうときは、何か根本的な見落としや間違いをしているものです。

そう、根本的なことでした。Goの根本的な決まり事を行っていないことが原因でした。
JSONで受け取る構造体定義のフィールド名の先頭を大文字にしていなかったことが原因でした。
もともと受け取っていた構造体配列の構造体のフィールド名は先頭大文字でしたが、新規追加されるフィールド名と構造体配列として追加したフィールド名の先頭を小文字にしていたことが原因でした。
外部公開するときのGoのシンプルな仕様ですが、Go内で構造体として定義するとき以外も同様で、そのことが抜けてました。
最初、渡し方や受け取り方の間違いではないかとそちらばかりに注意が向いたので気づくのが遅くなってしまいました。

React-hook-form でエラー(TypeError)が発生

React-hook-form で開発をしていてエラーがでるようになってしまった。

Uncaught TypeError: path.split is not a function
...split...
at renderWithHooks (react-dom.development.js:14985)
...split...

調べてみるとバージョンアップが原因だとわかった。
version 7 の記述に変更するとエラーはでなくなった。

version 6 ×

<input name='test' ref={register} />

version 7 〇

<input {...register('test')} />

v7移行ガイド
react-hook-form.com

SAXパーサーの parseメソッドに渡した InputStream の後始末

org.xml.sax.helpers.XMLReaderFactory.createXMLReader() で返されるパーサーの parseメソッドにInputSourceの引数で渡している InputStream が
処理後、closeしていなかったので、リソースが解放されていない可能性を調べてみた。

 lsof -p プロセスID|grep ファイル名

オープンしていたファイルはしばらくして表示されなくなったので close されているようだ。

XMLReaderFactory.createXMLReader() で返されるパーサーの実態クラスは org.apache. xerces . parsers.SAXParser

念のため parseメソッドを呼び出して処理後に InputStream の read をしてみると "Stream Closed" の IOException が発生した。

このパーサーオブジェクトの parseメソッドにInputSourceの引数として渡した InputStream はparseメソッド内で close されているので、呼び出し側はcloseする必要がなかった。

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;

import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.XMLReaderFactory;

    // ...

    File file = new File(fileName);

    InputStream input = null;
    try {
        input = new FileInputStream(file);

        XMLReader xmlRaeder = XMLReaderFactory.createXMLReader();
        xmlReader.parse(new InputSource(input));
        // ...
    }
    catch(IOException x) {
        // ...
    }
    catch(SAXException x) {
        // ...
    }
    finally {
        // 正常時は xmlReader.parseで InputStrem は close されている。
        if (input != null) {
            try { input.close(); } catch(IOException x) { .. }
        }
    }

※ java のバージョンは1.6.0_26

プログラマをする前

プログラマ・SEをする前はIT関係の営業を4年半やっていました。

大学は文系でプログラミングの経験はなく、ITとはまったく無縁の学生生活を送っていました。

なので、プログラマ・SEになることは就活の時点でまったく考えていませんでした。

最初に就職した会社には、就活期間の後半になんとか内定を頂けた次第で
この時は自分の学生生活を振り返り、後悔しきりでした。

営業の仕事は、ルート営業ではなく、新規に顧客を開拓してシステムを販売することです。
他に本社関連の案件でシステム導入した地方の客先に出張して現調・システム導入の立会いを
やっていました。

上司はバリバリの営業叩き上げのドスの聞いた声の強面部長でした。
入社してから3年くらいまでは部長によく怒られていました。

慣れるまでは楽な仕事ではなかったのですが、徐々に契約がとれてお客様が増えていくと、
日々の仕事は、上司からの苦言もなくなり自由にやらせてもらうことができるようになりました。

仕事は充実していったのですが年度評価に対して納得いかないことや疑問に思う事があり、
ある事がきっかけでソフトウェアを開発する違う企業に転職しました。

ある事というのは、仕事上でのちょっとした出来事です。