この記事は、Perl Advent Calendar 2024 10日目の記事(穴埋め)です。 9日目は@shogo82148で「Perl 5.41から、UTF-8で書かれたソースコードにはuse utf8が必須になります」でした。
以前、開発版のPerlで試した iterating over multiple values at a time 機能ですが、
Perl 5.35.5 の iterating over multiple values at a time を先取り Perl 5.40 から正式な機能として利用できるようになりました。
試してみた この機能を使うと、ハッシュ(連想配列)の全要素に対して操作したい、ということが簡単にできます。 前回と同じコードを試してみましょう。
use v5.40; my %hash = ( a => 'Alice', b => 'Bob', c => 'Charlie', ); for my ($key, $value) (%hash) { print "$key => $value\n"; } 警告が出力されずに問題なく実行できます。
a => Alice b => Bob c => Charlie もちろん3つ以上同時に取得することもできます。
この記事は、Perl Advent Calendar 2024 9日目の記事(穴埋め)です。 8日目は@xtetsuji(Tetsuji OGATA)で「時間を毎秒カウント出力するシェルスクリプトの遅れの考察」でした。
Perl 5.41.2(開発版)から source::encodingプラグマが追加されました。 このプラグマの追加により、UTF-8で書かれたソースコードでは use utf8 が必須になります。
TL;DR ソースコードの先頭に use utf8 って書いておけばOK。
use utf8の必須化 たとえば以下のコードにはUTF-8の文字列が含まれていますが、 use utf8 の指定がありません。
use v5.41; # こんにちは世界 このコードをPerl 5.41.2(開発版)で実行すると以下のようなエラーを吐いて終了します。
Use of non-ASCII character 0xE3 illegal when 'use source::encoding "ascii"' is in effect at hoge.pl line 3, at end of line Execution of hoge.pl aborted due to compilation errors. コメントアウトしてあっても日本語は使えないんですね。
正しく実行するには use utf8 を明示し、ソースコードがUTF-8で書かれていることを示す必要があります。
use v5.41; use utf8; # こんにちは世界 これは use utf8 をうっかり書き忘れることを防ぐための処置だそうです。
この記事は、Perl Advent Calendar 2024 5日目の記事(穴埋め)です。 4日目は@shogo82148で「Perl 5.40でtry/catch機能が安定版になりました」でした。
Perl 5.40.0 から、真偽値の排他的論理和を表す ^^ 演算子が導入されました。
背景 Perl には「コンテキスト(文脈)」と呼ばれる概念があります。 Perlはプログラム内の文脈によって、今扱っているデータをどんな種類(数値なのか文字列なのか)で解釈するかを決定します。
たとえば $x + $y は数値加算の演算子であり、$x や $y は数値コンテキストで解釈されます。 数値コンテキストではデータは数値として評価されます。 もし $x や $y に文字列が入っていた場合は、一度数値に変換してから演算が行われます。
そして、Perlにはコンテキスト毎に異なった演算子が存在します。 たとえば、「論理積」を表す演算子の場合、 「整数の論理積」「文字列の論理積」「真偽値の論理積(優先度高)」「真偽値の論理積(優先度低)」の4種類の演算子があります。 「論理和」や「排他的論理和」を加えて表にまとめてみると以下のようになります。
コンテキスト 論理積 論理和 排他的論理和 数値 & | ^ 文字列 &. |. ^. 真偽値(優先度高) && || 真偽値(優先度低) and or xor さて、この表をよく見ると「真偽値の排他的論理和」の部分にひとつだけ空白があります。 「この空白を埋めよう!」というモチベーションで追加されたのが ^^ 演算子です。 ^^ は両辺の真偽値コンテキストで評価し、その排他的論理和を計算します。
試してみた 実際に試してみました。
use v5.40; sub say_bool($v) { say $v ? "true" : "false"; } say_bool false ^^ false; say_bool false ^^ true; say_bool true ^^ false; say_bool true ^^ true; Perl 5.
この記事は、Perl Advent Calendar 2024 4日目の記事(代打)です。 3日目は@kfly8で「Perlの型ライブラリのkuraと組み込みのclassを一緒に利用できるようになりました」でした。
Perl 5.34.0 で導入されたtry/catch機能でしたが、今までは実験的機能の扱いでした。 しかし、Perl 5.40.0でついに正式な言語機能として扱われることになりました!
Perl 5.40.0のtry/catch機能 :5.40 feature bundle にも try feature が追加されました。 use v5.40 するだけで使えます。
use v5.40; try { die "dead"; } catch($e) { print "catch: $e"; } 実行結果は以下の通りです。
catch: dead at try-catch.pl line 4. まとめ Perl 5.40 で try/catch が使えるようになりました。
Perl 5.38 までの try/catch については以下の記事を参照。
Perl 5.34.0 の try-catch を触ってみる 新しい風が吹く、Perlの空に
tryとcatchで一筋の光
例外処理が簡単に
バグも恐れず、コードも輝く
未来を照らす、5.40
by CodeRabbit
明日5日目は@shogo82148で「Perl 5.40に真偽値の排他的論理和を表す新しい演算子が導入されました」です。 お楽しみに!
参考 Perl 5.
LEFT JOIN を何度も繰り返し、さらに FOR UPDATE しているMySQLのクエリーを見かけました。 毎回似たようなコメントをするのも面倒なので、そのようなクエリーの問題点をまとめておきます。 たとえばこんな感じのクエリーです。
SELECT * FROM `user` LEFT JOIN `user_prefecture` USING (`user_id`) LEFT JOIN `prefecture` USING (`prefecture_id`) WHERE `user`.`user_id` = 1 FOR UPDATE; TL;DR 以下の理由から、LEFT JOINとFOR UPDATEを同時に使うのはやめたほうがよい。
そもそもロックの範囲を間違えている可能性が高い デッドロックの危険性が高まる ギャップロックの可能性がある FOR UPDATE はロックの獲得のみに使用し、関連する情報を取得するのは別クエリーに分けよう。
LEFT JOINとFOR UPDATEを同時に使うのはやめよう 検証用に簡単なテーブルを作ってみます。
ユーザーは自分の居住地(都道府県)を設定できます。 自分の居住地を明かしたくないユーザーは、居住地を設定を省略することも可能です。 このような要件をもとに以下のようなテーブルを定義してみました。
-- ユーザー CREATE TABLE `user` ( `user_id` BIGINT PRIMARY KEY AUTO_INCREMENT, `name` VARCHAR(191) ); -- 都道府県のマスターデータ CREATE TABLE `prefecture` ( `prefecture_id` INTEGER PRIMARY KEY, `name` VARCHAR(191) ); -- ユーザーと都道府県の関連テーブル CREATE TABLE `user_prefecture` ( `user_id` BIGINT PRIMARY KEY, `prefecture_id` INTEGER, CONSTRAINT `user_prefecture_user` FOREIGN KEY (`user_id`) REFERENCES `user` (`user_id`), CONSTRAINT `user_prefecture_prefecture` FOREIGN KEY (`prefecture_id`) REFERENCES `prefecture` (`prefecture_id`) ); -- 初期データ INSERT INTO `user` (`name`) VALUES ("Ichinose"), ("Furusawa"), ("Inoriko"), ("Izu"); INSERT INTO `prefecture` (`prefecture_id`, `name`) VALUES (15, "新潟"); INSERT INTO `user_prefecture` (`user_id`, `prefecture_id`) VALUES (1, 15), (2, 15); 以下の初期データを投入してあります。
AWSでアジアパシフィック(マレーシア)リージョンが利用可能になりました!
Now open — AWS Asia Pacific (Malaysia) Region ついにオープン – AWS アジアパシフィック (マレーシア) リージョン それに合わせて p5-aws-lambda のビルド済みレイヤーも公開しました!
Perl本体(x64): arn:aws:lambda:ap-southeast-5:445285296882:layer:perl-5-40-runtime-al2023-x86_64:1 Perl本体(arm64): arn:aws:lambda:ap-southeast-5:445285296882:layer:perl-5-40-runtime-al2023-arm64:1 Paws(x64): arn:aws:lambda:ap-southeast-5:445285296882:layer:perl-5-38-paws-al2023-x86_64:1 Paws(arm64): arn:aws:lambda:ap-southeast-5:445285296882:layer:perl-5-38-paws-al2023-arm64:1 🐰新しい地域に、喜びの声、
AWS Lambda、広がる希望。
マレーシアの空に、夢が舞う、
みんなで使おう、楽しいクラウド!
うさぎも跳ねて、嬉しさ満点、
これからの未来、共に進もう! 🌟
by CodeRabbit
参考 Now open — AWS Asia Pacific (Malaysia) Region ついにオープン – AWS アジアパシフィック (マレーシア) リージョン shogo82148/p5-aws-lambda AWS::Lambda
GoとTypeScriptで Structured Field Values のパーサーを書きました。
github.com/shogo82148/go-sfv: Go版実装 github.com/shogo82148/sfvjs: TypeScript版実装 背景 そもそも Structured Field Values (SFV) とはなにか、なぜ登場したのか、という背景はこちらの記事をどうぞ。
Structured Field Values による Header Field の構造化 HTTP APIを開発していると、アプリケーション独自のHTTPフィールドを定義することがあります。 そういうときに、標準にしたがっておいたほうが何かと楽だろう、ということでSFVを採用しました。
しかしいい感じのSFVのパーサーがなかなか見つからなかったので、自作することにした、というわけです。
Go実装 Go のモジュールとして公開されているので、いつものように go get してきましょう。
go get github.com/shogo82148/go-sfv GoでSFVをパースする DecodeItem、DecodeList、 DecodeDictionary を使います。
net/http.Header.Valuesの戻り値を直接受け取れるよう、 各関数は []string を受け取るようにしました。
package main import ( "fmt" "net/http" "github.com/shogo82148/go-sfv" ) func main() { h := make(http.Header) h.Add("Example", `2; foourl="https://foo.example.com/"`) item, err := sfv.DecodeItem(h.Values("Example")) if err != nil { panic(err) } fmt.
先日npmへのパッケージ公開にチャレンジしてみました。
npmとjsrにパッケージを公開してみた (認証バッジ付) しかし2か月も経たないうちにビルドに失敗するようになってしまいました・・・。 何もしていないのに壊れた。
% deno run -A scripts/build_npm.ts [dnt] Transforming... [dnt] Running npm install... added 7 packages, and audited 8 packages in 4s found 0 vulnerabilities [dnt] Building project... [dnt] Type checking ESM... src/deps/jsr.io/@std/assert/1.0.2/assertion_error.ts:27:42 - error TS2304: Cannot find name 'ErrorOptions'. 27 constructor(message: string, options?: ErrorOptions) { ~~~~~~~~~~~~ src/deps/jsr.io/@std/assert/1.0.2/assertion_error.ts:27:42 - error TS4063: Parameter 'options' of constructor from exported class has or is using private name 'ErrorOptions'. 27 constructor(message: string, options?
元ネタ:
[JavaScriptの問題]
var a = 0.3 - 0.2;
var b = 0.2 - 0.1;
var c = a==b;
cの中身はどれ?
— RAO(らお)@けもケP-31 (@RIORAO) 2017年10月24日 正確な実数計算をやらされるJavaScriptくん #擬竜戯画 pic.twitter.com/ipE56C2YbV
— RAO(らお)@けもケP-31 (@RIORAO) 2017年10月26日 この件に関して、以下のような記事を書きました。
Go言語の浮動小数点数のお話 この記事のなかで「Goの定数は512bitの精度で計算されている」「有限精度のため、数学的な答えとは一致するとは限らない」というお話をしました。 しかし某電柱様から「記事中のコードを最新のGoで実行すると、記事の内容とは異なった結果が得られる」という情報を得ました。
問題のコード 動作が異なると報告があったのは以下のコードです。
package main import ( "fmt" ) func main() { const a = 0.3 - 0.2 const b = 0.2 - 0.1 var c = a == b fmt.Println(c) fmt.Printf("%e\n", float64(a-b)) } 数学的には 0.3 - 0.
新規に立ち上げたプロジェクトで firebase deploy を実行したところ、以下のエラーを吐いて失敗してしまいました。
Build failed: failed to Fetch: failed to download archive gs://gcf-sources-PROJECT_NUMBER-asia-northeast1/createUserOnUserCreate-5fd201fd-4b54-42b8-af5c-c3ca68fe3560/version-1/function-source.zip: Access to bucket gcf-sources-PROJECT_NUMBER-asia-northeast1 denied. You must grant Storage Object Viewer permission to PROJECT_NUMBER-compute@developer.gserviceaccount.com.
TL;DR 以下の設定を行います。
サービスアカウント PROJECT_NUMBER-compute@developer.gserviceaccount.com に「Cloud Build サービス アカウント(roles/cloudbuild.builds.builder)」のロールを付与 サービスアカウント PROJECT_NAME@appspot.gserviceaccount.com に「Firebase 管理者(roles/firebase.admin)」「サービス アカウント ユーザー(roles/iam.serviceAccountUser)」を付与 原因 原因は「Code Buildのサービスアカウントの仕様が変更になった」ことと「デフォルトのサービスアカウントへの自動的なロール付与を無効にする設定になっていた」ことでした。
Code Buildのサービスアカウントの仕様が変更になった 今まではサービスアカウント PROJECT_NUMBER@cloudbuild.gserviceaccount.com の権限を使用してビルドしていたのが、 サービスアカウント PROJECT_NUMBER-compute@developer.gserviceaccount.com に変更になりました。
Cloud Buildサービスアカウントが仕様変更(2024年4月29日から) デフォルトのサービスアカウントへの自動的なロール付与を無効にする設定になっていた 一部のGoogle Cloudサービスでは、APIを有効化したときにデフォルトのサービスアカウントが自動的に生成されます。 このとき生成されるサービスアカウントには編集者(roles/editor)が付与されます。
しかし、今回問題になったプロジェクトでは、組織ポリシーでロール付与が無効になっていました。
デフォルトのサービス アカウントへの自動的なロール付与を無効にする この設定の影響で、サービスアカウント PROJECT_NUMBER-compute@developer.gserviceaccount.com に一切権限がない状態でした。
また、Firebase Functionsを実行するためのサービスアカウントにも一切権限がありませんでした。
対策 各サービスアカウントに適切な権限を付与します。
具体的には以下の権限を付与しました。