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
https://amzn.to/44CzDFh
数式なども登場せず、LLM について過度な期待をもたせすぎず、それでいて未来への展望を冷静に語っている良書だと思います。
ChatGPT について学びたい人、特に文系の人にはオススメ。
https://github.com/square/okhttp/issues/3154
elasticsearch/opensearch 等では GET request に content-body をつける必要があるが、OkHttp3 では対応していない。強い気持ちがあるようだ。
ネクロマンサーでレベル50まで。
tier1でやった。
楽しかった。エクスプロージョンが使いこなせると楽しくなったかなー。
一般的なプログラミング言語に慣れていると「普通に考えたらデフォルトは machine native だろ」って考えがちだけど、Java の Byte buffer は big endian がデフォルトなので気をつけよう!!
めっちゃ時間溶けた。
https://docs.oracle.com/javase/jp/6/api/java/nio/ByteBuffer.html
普段は mybatis を使うことが多いのだが、Prototyping する機会があり、たまには Exposed など使ってみることにした。
Exposed は JetBrains 製なので kotlin と相性良さそうかなーと。
で、実際使ってみると以下のような困ったことがあった。
DB スキーマをコード上で表現可能だが、たとえば INDEX url(255)
みたいなのを表現する方法がわからん
MATCH AGAINST
とかを DSL で書けない
INSERT ON DUP UPDATE とかを雑に使おうとすると、ちょっとめんどい。
結局、複雑なクエリを使おうとすると、JDBC のレイヤまで降りていかなきゃいけない。
というわけで、今日もまた mybatis へと戻っていくのだった。
(実は Exposed でもやりようがあるのかもしれないが見つけられなかった)
Kweb がどうも日本語入力がうまくいかなくなったので諦めて普通の Ktor ウェブアプリに戻した。
機能的にはほぼ同じだがシンプルになった。Kweb で少しシンプルに書けるかなーと思ったのだが、そうでもなかったし、、
相変わらず微妙に速度が遅いのだが、、この遅さはなぜか DigitalOcean を使っている結果、シンガポールにデータベースサーバーがあるので、、というよくわからない理由によるものなので、RDSにでも移すかなぁ。
https://mcolotto.github.io/magic-research-demo/website/
Android 版をシコシコとやってた。いわゆる放置ゲー的なやつだけど、この手のやつでは一番おもしろかった。
トータルで 49日かかりました。
何が面白いかと言うとですね。。ゲームバランスが絶妙で、ボスが絶妙に倒せないのと、戦術を工夫しないと先に進めないようになっててめっちゃ楽しい。
転生するたびに見える景色が変わっていく感じがたまらないですな。
なんか知らんけど、 blog を更新しようとしたら落ちた。
kweb が kotlin-logging の 4 beta に依存してて、 class not found な状態に。悲しい。
しょうがないからアプリ自体も kotlin-loggin 4 beta に依存するようにして解決。
ついでに kweb 自体のバージョンも上げたのだが、普通の input box が、すげー微妙な挙動になってつらい。。日本語の入力時に入力途中の文字が入っちゃうというよくあるやつ。
kweb 飽きたし、そのうち全面的に書き直したいかもしれない。
SPA にするのが良いと思うが、どうしようかなぁ。
Watchdogs LEGION をクリアしてから youtube のレビューなどを見たところ、以下のような意見が散見された。
ロンドンは道が狭いからカーチェイスが楽しくない
ストーリーが薄味
Watchdogs LEGION も結構面白かったのに 1,2 のほうが良かったという意見が多いようなので、そんならやってみるかということでヤッてみた。
やってみるとじっさい、カーチェイス多い。カーチェイス多すぎるぐらい。あと 1 はドローンないからドンパチメインになりがち。
ストーリーもまぁ 1 とか 2 は濃い。2の世界観はなんというか、学生の正義の味方気取りのテロリストって感じでノリについていけない感じはありつつ。。
全体としては 1 も 2 も面白かった。LEGION は方向性としては面白い気がするので、AI の進化を取り入れていければ今後この方向性はもっとおもしろくなるんじゃないかなーと期待している。LEGION の良くないのは、キャラクターを収監されちゃうところな気はするのと、キャラクターごとの個性が弱いってところだと思う。RimWorld とかのほうがよほど思い入れが持ちやすいね。
寄り道しながら27時間ぐらいでクリア。
街中の人を採用できるというのが斬新だが、キャラに思い入れしにくいというのは本当にそう。
今後の AI 技術の発達によって、音声合成・会話合成がより進めばもっと自由度が生まれて楽しくなるかもしれない
色んなキャラがいるが、そんなにめっちゃいいスキルがあるかというとそうでもないので、採用しようっていうモチベが薄い
もう少しレアスキルもちとかいればな〜
育成要素があるともうちょい楽しいと思うけど、ごちゃごちゃしちゃうかも。
結局、SMG/LMG 持ってるやつが便利でそういうのばっかり使っちゃう
ハッキングしていくのは純粋に楽しい
流石にリリースから数年たってるのでバグはほぼ感じなかった
良くも悪くも UBI ゲームって感じで、良ゲー、ぐらいの感じ。
ストーリーがちょっと弱いというか、先が見えちゃうかも。
kotlin の dataframe 的なライブラリである krangl が deprecate されていた。
kotlinx.dataframe が後継なので、これを利用するようにするとよい。
ドキュメントが整備されていて、読みやすくなっている。dataframe 周りも kotlin で扱いやすくなって最高だ。
https://kotlin.github.io/dataframe/overview.html
kravis は kotlinx.dataframe ベースに変わっていた。
神ゲーだと思う。Atomic Heart でがっかりした直後だから余計にそう思うのかも。。
STANDARD 28.2時間 で B。Window gaming PC で Steam 版をクリア。弾がなくなることはほぼないかな。
ホラーというよりアクションって感じ。虫がいきなり出てきたところ以外で驚くことはないかな。
原作プレーしてない勢というか、スマホ版とかを昔ちょっとやったけど途中で操作性悪くて辞めた勢。
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 まで変更はなし。
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
https://openapi-generator.tech/docs/templating/#all-generators-core
openapi-generator で enum を制御するにはこのへんを参照。
x-enum-varnames
: 変数名
x-enum-descriptions
: description
という2つを使って構成する。
varnames はともかくとして descriptions は OpenAPI の spec に入っておくべき要素だと思う。
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
の名前を書けば読み取られます。
AbstractJavaCodeGen あたりを継承して以下のようにメソッドを上書きすれば抑制できる。
@Override
public boolean getUseInlineModelResolver() {
return false;
}
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);
}
}