Blog

SparkSQL で暗黙の型変換を抑制する

automatic type coercing が起きると期待しない結果になることがある。

select if('-999999999999' < 0, true, false) as s, if(-999999999999 < 0, true, false) as i

↑の結果が、s は false, i は true となる。 数字をうっかり文字列のまま使ってる場合、int の範囲を超えた場合に false になる。

こういう暗黙の型変換は困るケースも多いので、spark.sql.ansi.enabled を有効に設定することを検討する。

spark.conf.set("spark.sql.ansi.enabled", "true")

この環境下では、上記のクエリーは invalid input syntax for type numeric: -999999999999 と型変換エラーになる。

https://spark.apache.org/docs/3.4.1/sql-ref-ansi-compliance.html

大規模言語モデルは新たな知能か――ChatGPTが変えた世界 (岩波科学ライブラリー)

https://amzn.to/44CzDFh

数式なども登場せず、LLM について過度な期待をもたせすぎず、それでいて未来への展望を冷静に語っている良書だと思います。 ChatGPT について学びたい人、特に文系の人にはオススメ。

OkHttp3 では GET request に content-body が送れない

https://github.com/square/okhttp/issues/3154

elasticsearch/opensearch 等では GET request に content-body をつける必要があるが、OkHttp3 では対応していない。強い気持ちがあるようだ。

diablo4 のストーリーをやった

ネクロマンサーでレベル50まで。 tier1でやった。

楽しかった。エクスプロージョンが使いこなせると楽しくなったかなー。

Java の ByteBuffer の endian は big endian がデフォルト

一般的なプログラミング言語に慣れていると「普通に考えたらデフォルトは machine native だろ」って考えがちだけど、Java の Byte buffer は big endian がデフォルトなので気をつけよう!! めっちゃ時間溶けた。

https://docs.oracle.com/javase/jp/6/api/java/nio/ByteBuffer.html

Exposed を試した

普段は mybatis を使うことが多いのだが、Prototyping する機会があり、たまには Exposed など使ってみることにした。 Exposed は JetBrains 製なので kotlin と相性良さそうかなーと。

で、実際使ってみると以下のような困ったことがあった。

というわけで、今日もまた mybatis へと戻っていくのだった。

(実は Exposed でもやりようがあるのかもしれないが見つけられなかった)

自分の Blog admin site を書き直した

Kweb がどうも日本語入力がうまくいかなくなったので諦めて普通の Ktor ウェブアプリに戻した。 機能的にはほぼ同じだがシンプルになった。Kweb で少しシンプルに書けるかなーと思ったのだが、そうでもなかったし、、

相変わらず微妙に速度が遅いのだが、、この遅さはなぜか DigitalOcean を使っている結果、シンガポールにデータベースサーバーがあるので、、というよくわからない理由によるものなので、RDSにでも移すかなぁ。

magic research をクリアした

https://mcolotto.github.io/magic-research-demo/website/

Android 版をシコシコとやってた。いわゆる放置ゲー的なやつだけど、この手のやつでは一番おもしろかった。 トータルで 49日かかりました。

何が面白いかと言うとですね。。ゲームバランスが絶妙で、ボスが絶妙に倒せないのと、戦術を工夫しないと先に進めないようになっててめっちゃ楽しい。 転生するたびに見える景色が変わっていく感じがたまらないですな。

blog を更新しようとしたら、落ちた。

なんか知らんけど、 blog を更新しようとしたら落ちた。 kweb が kotlin-logging の 4 beta に依存してて、 class not found な状態に。悲しい。

しょうがないからアプリ自体も kotlin-loggin 4 beta に依存するようにして解決。

ついでに kweb 自体のバージョンも上げたのだが、普通の input box が、すげー微妙な挙動になってつらい。。日本語の入力時に入力途中の文字が入っちゃうというよくあるやつ。 kweb 飽きたし、そのうち全面的に書き直したいかもしれない。

SPA にするのが良いと思うが、どうしようかなぁ。

Marvel's Spider-Man: Miles Morales

https://www.playstation.com/ja-jp/games/marvels-spider-man-miles-morales/

PS5でクリア。 正当な拡張コンテンツという感じ。Spider man 2 も発売決定してるのでそれも楽しみですね。

Watchdogs 1/2 クリア

Watchdogs LEGION をクリアしてから youtube のレビューなどを見たところ、以下のような意見が散見された。

Watchdogs LEGION も結構面白かったのに 1,2 のほうが良かったという意見が多いようなので、そんならやってみるかということでヤッてみた。

やってみるとじっさい、カーチェイス多い。カーチェイス多すぎるぐらい。あと 1 はドローンないからドンパチメインになりがち。 ストーリーもまぁ 1 とか 2 は濃い。2の世界観はなんというか、学生の正義の味方気取りのテロリストって感じでノリについていけない感じはありつつ。。

全体としては 1 も 2 も面白かった。LEGION は方向性としては面白い気がするので、AI の進化を取り入れていければ今後この方向性はもっとおもしろくなるんじゃないかなーと期待している。LEGION の良くないのは、キャラクターを収監されちゃうところな気はするのと、キャラクターごとの個性が弱いってところだと思う。RimWorld とかのほうがよほど思い入れが持ちやすいね。

Watchdogs Legion クリア

寄り道しながら27時間ぐらいでクリア。

krangl が deprecate されていた

kotlin の dataframe 的なライブラリである krangl が deprecate されていた。

kotlinx.dataframe が後継なので、これを利用するようにするとよい。

ドキュメントが整備されていて、読みやすくなっている。dataframe 周りも kotlin で扱いやすくなって最高だ。 https://kotlin.github.io/dataframe/overview.html

kravis は kotlinx.dataframe ベースに変わっていた。

BioHazard RE:4 クリア

神ゲーだと思う。Atomic Heart でがっかりした直後だから余計にそう思うのかも。。 STANDARD 28.2時間 で B。Window gaming PC で Steam 版をクリア。弾がなくなることはほぼないかな。 ホラーというよりアクションって感じ。虫がいきなり出てきたところ以外で驚くことはないかな。 原作プレーしてない勢というか、スマホ版とかを昔ちょっとやったけど途中で操作性悪くて辞めた勢。

freemarker の js_string の歴史

freemarker の js_string がどのような変遷をたどってきたのかをまとめてみた。

2.3

Date of release: 2004-June-15

https://freemarker.apache.org/docs/versions_2_3.html

New built-ins for Java and JavaScript string escaping: j_string and js_string

2.3.1

Date of release: 2005-01-04

https://freemarker.apache.org/docs/versions_2_3_1.html

The js_string built-in now escapes > as > (to avoid ).

2.3.20

Date of release: 2013-06-27

https://freemarker.apache.org/docs/versions_2_3_20.html

Bug fix [390] (and other improvements): ?js_string and ?json_string didn't escape the u2028-u2029 line terminators (problem for JavaScript) and the u007F-u009F control characters (maybe a problem in JSON, depending on implementation). Furthermore, the escaping of , <, and > become safer in that now they are escaped whenever it can't be guaranteed that they won't be part of <!, ]]> or </. Earlier they were only escaped when it was known that they are part of these patterns, thus it was possible to assemble these patterns from two adjacent interpolations. Additionally, from now on <? and --> also count as dangerous patterns, and will trigger < and > escaping.

まとめ

2.3.20 以後、2023年4月現在の最新版である 2.3.32 まで変更はなし。

Java 9 以後での InputStream を String にするやり方

commons-io で IOUtils.toString(inputStream, StandardCharsets.UTF_8) としているケースは、Java 9 以後なら new String(inputStream.readAllBytes(), StandardCharsets.UTF_8) と書けて便利。

https://www.baeldung.com/convert-input-stream-to-string

OpenAPI の enum を使いこなす

https://openapi-generator.tech/docs/templating/#all-generators-core

openapi-generator で enum を制御するにはこのへんを参照。

x-enum-varnames: 変数名 x-enum-descriptions: description

という2つを使って構成する。

varnames はともかくとして descriptions は OpenAPI の spec に入っておくべき要素だと思う。

openapi-generator の custom generator を gradle plugin から使う

https://github.com/OpenAPITools/openapi-generator/issues/6190

openapi-generator は ServiceLoader で generator を探すので、CLASSPATH に custom generator を突っ込むことができれば良いです。

CLASSPATH にカスタムジェネレータを突っ込むには buildSrc を使えば良いので、例えば以下のように階層構造を作れば良いですね。

.
├── build.gradle.kts
├── buildSrc
│   └── src
│       └── main
│           ├── java
│           │   └── my
│           │       └── own
│           │           └── Generator.java
│           └── resources
│               └── META-INF
│                   └── services
│                       └── org.openapitools.codegen.CodegenConfig
├── gradle
│   └── wrapper
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle.kts

buildSrc/src/main/resources/META-INF/services/org.openapitools.codegen.CodegenConfig の中に my.own.Generator の名前を書けば読み取られます。

openapi-geneartor の java generator で NantokaAllOf.java が大量にできる件

AbstractJavaCodeGen あたりを継承して以下のようにメソッドを上書きすれば抑制できる。

    @Override
    public boolean getUseInlineModelResolver() {
        return false;
    }

Rust から NSLog を呼びたい

Mac OS においてデバッグするときには、NSLog を呼ばないととにかくやりづらい、というときがあります(InputMethodKit を使った開発をするときなどが特にそうです)。 そんなときには、以下の様にすると良いでしょう。

use cocoa::base::{id, nil};
use cocoa::foundation::NSString;


#[link(name = "Foundation", kind = "framework")]
extern {
    pub fn NSLog(fmt: id, ...);
}

fn main() {
    unsafe {
        NSLog(NSString::alloc(nil).init_str("Hello, %@"), NSString::alloc(nil).init_str("world"));
    }
}

Dependency は以下のように Cargo.toml に記述します。

[package]
name = "rust-nslog-sample"
version = "0.1.0"
edition = "2021"

[dependencies]
cocoa = "0.24.0"

さて、とはいえ毎回 NSString だなんだと書くのはめんどくさい、というのはあるかも。 せめて最初の引数はマクロ化したいですよね。

↓マクロ化するならこんな感じかな?

use cocoa::base::{id, nil};
use cocoa::foundation::NSString;


#[link(name = "Foundation", kind = "framework")]
extern {
    pub fn NSLog(fmt: id, ...);
}

macro_rules! NSLog {
    ( $fmt:expr ) => {
        unsafe {
            NSLog(NSString::alloc(nil).init_str($fmt))
        }
    };
    ( $fmt:expr, $( $x:expr ),* ) => {
        unsafe {
            NSLog(NSString::alloc(nil).init_str($fmt), $($x, )*)
        }
    };
}

fn main() {
    unsafe {
        NSLog!("Hello, %@ %d", NSString::alloc(nil).init_str("world"), 5963);
    }
}