追記

いがいが日記


2022-01-08 [長年日記]

_ COVID-19 対応生活日記

昨年末は10月頃から感染者が順調に減り、東京の感染者が、2桁人の日々が続いた。12月に新株オミクロン株が発見されてから状況は一変、楽観ムードから第6波を迎えるようになった。12月は入国待機を厳しくして水際対策をして効果もあったのかもしれないが、年が変わるタイミングで増加が加速、1/7現在で東京の感染者は日に900人になっていて、このあとまだ増えそうだ。

オミクロン株は、というか2回のワクチンの効果なのか、重症率はかなり下がっているようだ。それでも感染者数が過去最高の東京都で約5000人を上回るのは確実視されているレベルで感染が広がっている。3回目の接種も前回から8か月後に予定されているが、その前の抗体値が下がるタイミングで感染が広がっていくと予想されている。日本はワクチン接種者が1億人を超える高い接種率を獲得しているが、それでもオミクロン株は感染を続けている。世界はこの状況が少し早く始まっていて感染者が増えているが、株式市場などでそれほどは問題視されてない程度には楽観的なようだ。

近所の処方箋に対応する大きなドラッグストアでは国の補助でPCR検査を無料で受診できるようになった。店舗で唾液を試験管に採取して検査センターへ送り2日後に結果をメールで教えてくれる仕組みだ。帰省の前に使わせてもらった。仕組みを構築しているのがすごいと思った。結果陰性の通知をもらって少し安心感を持てる。


2021-12-25 [長年日記]

_ 入門書におけるRuby2.3からRuby3.0そしてRuby3.1への変化

igaigaです。これは Ruby Advent Calendar 2021 の25日目の記事です。昨日はmrknさんの 「来年リリースする bigdecimal 3.2 はどうしようかな」 でした。BigDecimal、長い間ずっと進化してきていてすごいです。

私は 「ゼロからわかるRuby超入門」 という初学者向けの入門書籍を2018年に書きました。発刊当時の最新のRubyはバージョン2.5で、この書籍ではRuby2.3から2.5までのバージョンに対応させて書きました。Ruby2.3は当時のmacOSにデフォルトで入っているバージョンで、大学などの講義で使うときにインストール不要で使えるようにこのバージョンも対象に入れました。

このRuby超入門、今年2021年の夏にひっそりとRuby3.0対応をしました。現在物理書籍として流通している第3刷以降では新しい内容になっています。改訂ではないので大きな変更はできなかったのですが、Ruby2.3や2.4だけで必要だった記述を削除したり、Ruby3.0までで変更になった点を更新しています。

この記事ではその作業を振り返って、Rubyの基礎的な範囲でのバージョンによる進化を書いていきます。

また、増刷ごとに読者のみなさまからのフィードバックを反映し、誤字の修正のほか、わかりづらい表現を変更するなどの作業をいれています。特に顧問先の フィヨルドブートキャンプ の受講生さんからたくさんのフィードバックをいただきました。この場を借りて感謝いたします。また、フィヨルドブートキャンプではRuby超入門の 講義動画 をつくりましたので、動画で学びたい方はご検討いただけましたら。

Ruby2.4でのbinding.irbの導入

Ruby2.4でbinding.irbと書くことでコード中で実行を一時停止してデバッグすることが可能となりました。入門書においてこれは革新的な変化で、Rubyをインストールしたらすぐに使えるというのが大きいです。もしもこの機能がないとpryなどのGemをいれることになりますが、その場合はGemについての説明が必要になり、これはRuby超入門では全11章中の第10章で登場するのを待たないといけなくなります。デフォルトで使える機能として入ったおかげで、2章でbinding.irbを利用したデバッグの方法を説明することができました。また、Ruby2.5では require "irb" も省略可能になったのも嬉しい変更です。

Ruby2.4でのArray#sumの導入

Ruby2.4でArray#sumが導入され [1,2,3].sum と書けるようになりました。このメソッドは説明の例題として使いやすいので例として登場させました。ちなみにRuby2.3向けには代わりに inject(:+) を使っていました。injectでは特別に inject(&:+) の&を省略できるのが懐かしいですね。

Ruby2.4でのNet:HTTP.postの導入

Ruby2.4でNet:HTTPのPOSTをかんたんに書けるようになりました。

require "net/http"
require "uri"
require "json"
uri = URI.parse("https://www.example.com")
result = Net::HTTP.post(uri, {mocha: 400}.to_json, "Content-Type" => "application/json")
p result

直感的に書けますね。このコード、Ruby2.3まではどう書いていたかというと次のようになります。

require "net/https"
require "uri"
require "json"
uri = URI.parse("https://www.example.com")
request = Net::HTTP::Post.new(uri.request_uri, "Content-Type" => "application/json")
request.body = {mocha: 400}.to_json
https_session = Net::HTTP.new(uri.host, uri.port)
https_session.use_ssl = true
response = https_session.start do |session|
  session.request(request)
end
p response

こちらは覚えるのがちょっと大変でした。Net::HTTP#postメソッドを使うと1メソッドで書けて便利になっていることが分かります。

Ruby2.4での正規表現の match? メソッド導入

Ruby2.4で正規表現マッチを行う match? メソッドが導入されました。

"カフェラテ".match?(/ラテ/)

Ruby2.3では =~ を使うように書きました。書籍にとっては真偽値を返すメソッドは末尾が?で終わる旨を説明できる例が増えるのでありがたい追加です。現実のコードもかなり読みやすくなったと感じています。

Ruby2.4でFixnumとBignumがIntegerへ統合

これは利用する側ではほとんど影響はなく、エラーメッセージやclassメソッドの結果が異なるくらいでした。Ruby core内部では大きな変更だったのではないでしょうか。(どうなのだろう?) 現実のコードではバージョンアップ当初はFixnumやBignumクラスがないよ、というエラーがよく出ていたのが懐かしいです。

追記(2022/01/09: FixNum, BigNumをFixnum, Bignumへ修正しました。コメントありがとうございました。

Ruby2.5でブロック内でbeginなしのrescueが書けるようになった

地味ですが、インデントが減るので読みやすくなりますね。メソッドでも同様に書けます。

bill = 100
numbers = [0, 1, 2]

numbers.each do |number|
  warikan = bill / number
  puts "1人あたり#{warikan}円です"
rescue ZeroDivisionError
  puts "おっと、0人では割り勘できません"
end

Ruby2.6からbundlerがデフォルトでインストールされる

これも神変更。今までは「BundlerでGem群をインストールするには3つの手順を踏みます。Bundlerのインストール、Gemfileの作成、bundle installコマンドの実行です。」となっていた手順が2つで済むようになりました。本当にありがたい。仕事でも新しくつかうRubyのバージョンをインストールしたあとにbunlde installしてbundlerがありませんというエラーを出すことがよくあったので、それがなくなってかなり楽になった。

Ruby2.7でprivateメソッド呼び出しのルールが変更

「private なメソッドはレシーバ付きでは呼びだせない」というルールから、「self.methodの形式でも呼び出し可能」に変更されました。今までprivateメソッドが呼べていた範囲内ではself.と書けるはずなので、privateメソッドを書ける場所が増えたわけではないです。

これは入門書ではかなり説明が難しくなってちょっと困っています。Ruby超入門では最低限の文章変更にとどめて、「privateなメソッドはレシーバを指定した呼び出し方ができない」といった説明にしています。self.methodの形式はselfだけが許可されるのでレシーバを指定しているわけではない、という解釈です。意図としては間違っていないと思うのですが、もっとうまい説明方法があったら教えてください。

Ruby2.7でパターンマッチが導入

case inで書けるパターンマッチがRuby2.7でexperimentalで追加され、Ruby3.0で正式版になりました。Ruby超入門では変更が大きくなってしまうのでまだ書けていませんが、書くならばcase whenのときにcase inもあるよとだけ伝えて、正規表現の節または次の節でパターンマッチという便利な道具もあると書き足したいと思っています。改訂のチャンスがあれば書きたいので、改訂できるくらい売れるようにみなさん書籍の宣伝よろしくお願いします。

Ruby2.7でobject_idの仕様変更

object_idがメモリ番地ベースだったのに代わり、なんらかの通し番号に変更されました。コンパクションGCが導入されてメモリ番地が変更されるケースへの対応だと考えています。利用者側からすると「表示される数値の桁が少なくなったな」と気づくくらいでしょうか。Ruby超入門ではオブジェクトが同一であることの説明でオブジェクトIDをつかっているので、オブジェクトの識別番号としての意図が残ってくれたのは本当によかったです。

Ruby2.7でEnumerable#tallyが追加

章末の練習問題に「文字列"caffelatte"の中で使われているアルファベットと、その回数を数えてください。」という問題があります。これはハッシュを生成してキーに文字、値に回数をカウントしていってもらうのを意図した問題でした。Rubyの本だと問題を作っても1メソッド2メソッドで解けてしまうことも多いのですが、プログラミングの練習としてはもう少し長く3手、5手かかる問題が欲しいのでかなり考えて作った問題で、お気に入りの問題でもありました。

Ruby2.7から追加されたEnumerable#tallyを使うと、"caffelatte".chars.tally の2メソッドで同様の結果が得られます。Rubyが便利になっていくと練習問題作成は難しくなっていく例です。いたしかたないです。

Ruby3.0でWebrickが標準添付ライブラリから除外

10章ではSinatra gemをつかってWebアプリの基礎について説明しています。SinatraをつかうとSinatraが仕様変更したりして将来動かなくなることもあるのでは?と執筆時に検討はしていたのですが、Webrickが外れるところまでは予想していませんでした。脆弱性対応は本当に大変なので妥当な判断なので、予想できてもよかったなとも思いますが、執筆時は標準添付ライブラリのGem化もまだ始まってなかった?と思うので、その状況では確かに難しいなとも思います。

Ruby3.0ではgem install webrickでインストールしてください。これは書籍のWeb正誤表にも載せていたのですが、エラーで動かなくなることもあり、Ruby3.0でRuby超入門の範囲で一番聞かれることが多かった質問でした。3刷では変更対応済みです。

Ruby3.1へ

Ruby3.1では新しいデバッガであるdebug.gemが標準添付され、今から本を書くならば、デバッグについての記述も書籍の前半に説明を少なく書けるのはありがたいですし、書籍の学習を進める上でのデバッグ方法としても活用できて便利になります。Ruby2.7で入った新しいirbも色がついて見やすく使いやすくなりました。

また、Ruby3.0で導入された型定義ファイルRBSとその周辺ツールも整備が進み、エディタに型情報をサジェスト表示したり、呼び出せるメソッド一覧を選ぶこともできるようになりました。これらも学習の助けになりそうです。Rubyで書かれるコードでの変数名などの命名にこれらのツールが影響を与えるのかどうかも興味深いです。

このように見てみると、入門書の範囲でもRubyは便利な変更がいろいろと入り、それでいて互換性が壊れるような変更はとても少ないことがわかります。Rubyの進化を提供してくれているコミッタのみなさんに本当に感謝します。

書籍を書くときに感じたのは、Rubyで入門書を書くと説明が少なくて済むということです。他の言語の入門書を参考に読んでいると「これはRubyの場合は説明の必要がない部分だな」という部分がいろいろとありました。言語仕様としてシンプルで覚えやすいルールが行き届いていたり、記述量が少なくて済むこと、組込ライブラリのクラス群によく使う便利なメソッドが用意されていること、などがその要因かもしれません。

一方でエディタでのメソッド入力補完が弱いことは弱点だったかと思いますが、それが改善されていっていることはとても嬉しいです。また、この本を書くときに感じたbinding.irbがすぐに使えるありがたさと同じことが、debug.gemでも感じられるかもしれません。これらの改善は学習カリキュラムにも良い影響を与えていると感じています。

Ruby3.1のリリースは今日予定されています。みなさん引き続き良いRubyライフを!

本日のツッコミ(全3件) [ツッコミを入れる]

_  [細かいことですが,FixNum,BigNum は正しくは Fixnum,Bignum ですね。 private..]

_ otn [「privateなメソッドは任意のレシーバを指定した呼び出し方ができない」 「privateなメソッドはレシーバを..]

_ igaiga [コメントありがとうございます!Fixnum, Bignumを修正しました。 privateなメソッドの説明もあ..]


2021-12-17 [長年日記]

_ Ruby3.0キーワード引数仕様変更に伴う書き換えをしたので調べたことのまとめ

igaigaです。この記事は Ruby Advent Calendar 2021 の17日目の記事です。昨日はフィヨルドブートキャンプでもお世話になっているyuuuさんの mruby-esp32-app-mirbをESP32で動かしてみた - panicの原因を見つけるまでの過程 でした。マイクロデバイスは胸が躍りますよね。

キーワード引数の仕様変更

Ruby2.7と3.0でキーワード引数の非互換を伴う仕様の整理が行われました。先日、Ruby2.6から2.7にバージョンアップすることがあり、この変更での書き換えを調べたのでまとめます。

また、本編とは直接関係ないですが、Ruby2.7.1から2.7.2へのバージョンアップでdeprecated カテゴリの警告はデフォルトで出力されなくなる変更が入ったので、Warningを出力するときは以下のようなオプションを指定します。 -W:deprecated の代わりに -W と書くとさらに広い範囲で全ての警告を表示します。

$ ruby -W:deprecated foo.rb
$ RUBYOPT='-W:deprecated' bin/rspec spec/foo_spec.rb

参考資料

以下の記事を参考にしました。特にmameさんの記事にたくさん助けられました。ありがとうございました。

概論(mameさんの記事より抜粋)

Ruby 3.0で、キーワード引数が通常の引数とは独立した引数になりました。これは非互換な変更になっています。

# キーワード引数を受け取るメソッド
def foo(key: 42)
end

foo(key: 42)      # OK: キーワード引数を渡している

opt = { key: 42 }
foo(opt)          # NG: 普通の引数を渡しているのでエラー(2.7では警告付きで動く)
foo(**opt)        # OK: ハッシュを明示的にキーワードに変換している

Ruby2.7までは普通の引数をキーワード引数に暗黙的に変換していましたが、3.0からはこの暗黙的変換を行わないようになりました。

ただし、キーワード引数から普通の引数への暗黙的変換は維持されています。削除するには互換性の影響が大きすぎるためだそうです。次のコードはRuby 3.0でも動作します。

# 普通のオプショナル引数を受け取るメソッド
def foo(opt = {})
end

foo(key: 42) # OK: キーワード引数が暗黙的に普通の引数に変換される

# # ↑は動きますが、今後は次のように書くのがおすすめです
# def foo(**opt)
# end

受け取った引数を別メソッドへ委譲するケースでのキーワード引数仕様変更

基本形

受け取った引数をそのまま全て別のメソッドの引数として渡すケースを考えます。Ruby2.7までは次のようなコードでした。

def foo(*args, &block)
  target(*args, &block)
end

Ruby3.0では次のようなコードになります。

def foo(*args, **kwargs, &block)
  target(*args, **kwargs, &block)
end

メソッド内で引数を変更しなければ、上記のコードと同じ動作を、以下のように委譲記法 ... で書けます。

def foo(...)
  target(...)
end
引数委譲記法 ... の拡張

引数委譲記法 ... では、先頭側の引数は変更できるようになっています。たとえば次のような書き方です。

def foo(arg1, ...) # 引数の先頭1つ目をarg1に入れ、残りは...で受け取る
  target(...) # 引数の先頭1つ目を抜いた残りを渡す
end

Ruby3.0で ... の先頭を取り除いたり、新しい値を追加できるようになりました。Ruby2.7へもバックポートされています。nagachikaさんありがとうございます。

Arguments forwarding (...) now supports leading arguments. Feature #16378

Ruby2.7での該当commit(動作確認して、Ruby2.7.3で入っていることを確認): https://github.com/ruby/ruby/commit/27fca66207f2c35f2f44f6a7cbbe6fd153546082

以下、mameさんのRuby3.0リリース時の記事より


https://techlife.cookpad.com/entry/2020/12/25/155741

キーワード引数の分離の悪影響の1つに、引数を委譲するのがめんどうになることがあります。そのため、Ruby 2.7では引数を委譲するための構文が導入されたのですが、引数を一切変更できないので使えるケースが限定されていました。

Ruby 3.0では、次のように、先頭の引数を取り除いたり、新しい値を追加したりすることが許されるようになりました。

def method_missing(meth, ...)
  send(:"do_#{meth}", ...)
end

先頭の引数以外はやはり変更できないのですが、これだけでも多くのケースが救われるという声が前述のヒアリングスレッドなどでも聞かれたため、導入されました。


実際に私の遭遇したケースでも先頭側の引数だけを取り除いて使いたいケースだったので、この機能で対応できました。

引数委譲記法 ... のサンプルコード

Ruby2.7.3, 3.0.3で実行して同様の結果で動作しました。 Ruby2.7.2ではエラー(syntax error, unexpected (... def foo(arg1, ...))になりました。

class Example
  def foo(arg1, ...) # 引数の先頭1つ目だけarg1に入れ、残りは...で受け取る
    p arg1 #=> :first
    bar(...) # 引数の先頭1つ目を抜いた残りを渡す
  end
  def bar(...)
    p(...) #=> "second", {:third=>3, :forth=>4}
  end
end

Example.new.foo(:first, "second", third: 3, forth: 4)

なお、上記のコードでの受け取り側引数arg1はarg1, arg2, arg3 と複数でも動作しました。

Ruby2.7 or Ruby3.0でのキーワード引数書き換え方法

https://www.ruby-lang.org/en/news/2019/12/12/separation-of-positional-and-keyword-arguments-in-ruby-3-0/

"Handling argument delegation" を日本語訳したもの。

Ruby 2.6以前

Ruby 2では、*rest引数と&block引数を受け取り、その2つをターゲットメソッドに渡すことでデリゲーションメソッドを書くことができる。この動作では、位置引数(positional argument)とキーワード引数の自動変換により、キーワード引数も暗黙のうちに処理される。

def foo(*args, &block)
  target(*args, &block)
end
Ruby 3.0以降

キーワード引数を明示的に委譲する必要があります。

def foo(*args, **kwargs, &block)
  target(*args, **kwargs, &block)
end

また、Ruby 2.6 以前との互換性を必要とせず、引数を変更しない場合は、Ruby 2.7 で導入された新しいデリゲーション構文 (...) を使用することができます。

def foo(...)
  target(...)
end
Ruby 2.7

要約: Module#ruby2_keywords と delegate *args, &block を使えばいいのです。

ruby2_keywords def foo(*args, &block)
  target(*args, &block)
end

ruby2_keywordsはHashの最後の引数としてキーワード引数を受け取り、他のメソッドを呼び出す際にキーワード引数として渡します。

実際、Ruby 2.7 では多くの場合、この新しいスタイルのデリゲーションが可能です。しかし、既知のコーナーケースがあります。次のセクションを参照してください。

Ruby 2.6以前, 2.7, 3.0以降で動く書き方

要約: やっぱり Module#ruby2_keywords を使えばOK

ruby2_keywords def foo(*args, &block)
  target(*args, &block)
end

残念ながら、Ruby 2.6 以前のバージョンでは新しいデリゲーションスタイルを正しく扱えないため、古いスタイルのデリゲーション(つまり **kwargs がない)を使用する必要があります。これがキーワード引数分離の理由の一つです。詳細は最後のセクションで説明します。また、ruby2_keywordsを使うと、Ruby2.7や3.0でも古いスタイルのまま実行することができます。2.6以前ではruby2_keywordsは定義されていませんので、ruby2_keywords gemを使うか、自分で定義してください。

def ruby2_keywords(*)
end if RUBY_VERSION < "2.7"

もしあなたのコードがRuby 2.6以前で動作する必要がなければ、Ruby 2.7の新しいスタイルを試してみてもよいでしょう。ほとんどの場合、うまくいきます。しかし、以下のような不幸なコーナーケースがあることに注意してください。

def target(*args)
  p args
end

def foo(*args, **kwargs, &block)
  target(*args, **kwargs, &block)
end

foo({})       #=> Ruby 2.7: []   ({} is dropped)
foo({}, **{}) #=> Ruby 2.7: [{}] (You can pass {} by explicitly passing "no" keywords)

空のHash引数は自動的に変換されて**kwargsに吸収され、デリゲーションコールは空のキーワードHashを削除するので、targetに引数は渡されない。私たちが知る限り、これは唯一のコーナーケースです。

最後の行で述べたように、**{}を使うことでこの問題を回避することができます。

本当に移植性が心配なら、ruby2_keywords を使ってください。(Ruby 2.6以前では、キーワード引数には多くの問題があります。) ruby2_keywordsはRuby 2.6が終了した後、将来的に削除されるかもしれません。そのときは、キーワード引数を明示的に委譲することをお勧めします(上記のRuby 3のコードを参照)。


2021-12-07 [長年日記]

_ 鉄塔から飛ぶ電波はあの川を越えて届くのか

おはようございます。igaigaです。2021年12月7日の、朝です。(ここでタイマーセットを忘れる) このテキストはやんちゃクラブリスナーアドベントカレンダー2021、7日目の記事です。昨日はkatsyoshiさんの 「やんちゃクラブとRubyistと川」 でした。稲田堤の川の家、行ってみたかったなぁ。

今日のハムのコーナー。私もbashさんと同じくアマチュア無線4級の免許を中学生のときに取りました。群馬に住んでいたので、高崎か、もしくは東京か、ちょっと遠くへ試験を受けに行った覚えがあります。中学生だと当然試験対策本に書いてあることはほとんど理解できなかったので、問題と答えのセットを暗記してがんばったと思います。その後、高専の電気科に入学することになり、電磁気学や電波工学、電気法規といった科目に悩まされることになりますがそれはまた別の話。

今日の話の主役は私ではなく父です。私が免許を取ったときに父のお下がりでもらった無線機(ハンディではなく固定機でした)は、当時の機械によくあったアナログの計器針がたくさんついた、大きさもちょっとした音響アンプくらいあるすごいものでした。父はより上位の級(2級?)の免許を持っていて、かなりのハム活ガチ勢でした。

ある日、父は庭にアマチュア無線のアンテナを載せる鉄塔を建てました。高さは2階を超えていたので10m程でしょうか。穴を掘り、コンクリ?を流しこんで土台をつくり、1辺50cm程の三角柱形に金属のポールを組み上げて鉄塔はできました。当日は親戚や友人の方々が大勢きてみんなでわいわい作業していて、子供心(おそらく当時7歳程)にもすごい工事をしているのだなと思っていました。このアンテナでかなり遠くまで交信していたと言っていましたが、具体的にどういう理屈で交信できていたのかとか詳しく聞いておけばよかったと今は思います。そういえば天候に大きく影響されると言っていた気がしますし、そんなことを高専の講義で習った記憶もあります。「おたく、変調浅いよ」とか言ったり言われたりしていたのでしょうか。

そんな父が交信するのをよく眺めていた、というかコタツで過ごしていると父が交信していたので、父のコールナンバーの呼び方(LXOだったのでリマ、エックスレイ、オスカー)や五十嵐の伝え方(いろはのい、かわせのかに濁点、・・・)といった定型句は今でも空で言えます。自分のコールナンバーのものは忘れたので言えません。子供の頃の記憶はすごいですね。

定型句のやりとりをしたあと、3往復程天気とか雑談をして交信を終了していたようでしたが、仲が良い友人とは長く話していたような気がします。当時、電話も定額制という制度がなかったので無線は長く雑談ができる良い手段だったのかもしれません。初めての人には「カードも送りますね」と言ってたのですが、あれはどうやって送っていたのでしょう。住所を交換していたのか、もしくは無線協会?とか公的機関が仲介をしてくれるのか。特にここでググったりはしないので、気になる人は調べてみてください。それでいいんですよ。

あ、タイマー動いてなかった。長くなったのでこの辺で終わりにします。今後のやんちゃクラブでハムの謎が解かれていくかもしれないので、たのしみにしています。

明日のやんちゃクラブリスナーアドベントカレンダー2021 は、やんちゃクラブのエバンジェリストことsuginoyさんです。


2021-12-01 [長年日記]

_ M1 MacBookPro 14inch

新しいMBPが出たタイミングで購入してセットアップもほぼ終わった。M1のマシンとしては去年のMacBookAirについでの2機種目の発表。私が使う初めてのM1マシンになった。シリコン不足で納品に時間がかかるかと思ったが、10月の発売日に購入して11月には届いたのでいつも通りくらいのスケジュール。GPU作業はそんなにしないので、M1 Proでもよかったと思うが、メモリ帯域が太いとあったのでM1 Maxを選んでみた。メモリも盛れるだけ盛って64GB。

セットアップは予想外にスムースで、Homebrewの導入も、Rubyのビルドも、EmacsのビルドもIntelマシンと同じ手順でできた。先人のみなさんのおかげだ。Dockerもレア機能をつかったりしていなければ動くようで、Rubyの公式コンテナは何事もなく動いた。今のところ動いていないのはVirtualBoxとVMWareだけだ。WindowsはArm版の提供がなさそうなので、この先Windowsを動かすのが大変そうだ。

速度は速い、というか前は時々あったひっかかるタイミングがほぼなく、快適な感じだ。ディスプレイも外付けで2枚差ししているが問題ない。体感できる中ではブラウザが速く、GMailの起動が目に見えて速いし、twitterで高速スクロールしてもがんばってレンダリングしている。ほかはRubyのビルドがIntel版と同時に実行したところ、M1は3倍の速さでビルドしていた。bundle installも速くなっているのかもしれない。そして、ファンがまだ一度も回っていない。温まり具合としてはそこそこ温かくなり、がんばってつかえば暖を取れるレベル。普通につかっていると常温よりも少し温かくなるかなくらいだ。総評としては快適につかっている。

14inchという大きさが今回登場して、形も弁当箱のように厚くなった。13inchと比べると重くて暑くて持ち運びには不便だが、持ち歩く機会は少ないのでいいかなと思う。

画面はノッチがついてカメラの左右も使えることになりかなり広く感じる。発熱は全然ないかと思ったらあったかくなるので、むしろ冬は好都合。標準充電器が90W超なので、ディスプレイ給電が追いつくかは少し心配。しかし前のIntelMBP13inchでも最近はDockerをガンガン使うとディスプレイ1枚の給電だと足りなくて2枚で賄っているので、同じくらいなのかなと予想している。

それにしてもこの時代に税込で40万円を超えるマシンを買うとは思わなかった。(ところで前回は税別表記だったのが税込表記になっていた。)おそらく今まで買ったマシンの中では一番高い。昔買ったPowerMacG5よりも高いのでは。前回まではしばらく30万円以下で買えていたので、M1になったら安くなると思っていたのは幻想だった。スペックのメモ。

  • A2442
  • M1 Max CPU 10 Core, GPU 32Core
  • 64GBメモリ(標準16GB)
  • 512GB SSD (標準)

追記