突然思い出して随分前のネタを引っ張り出してきました.
OCaml と Scala のパターンマッチ構文は共に match
というキーワードを使いますが, 前置 / 後置が異なるため, 交互に書いていると混乱して結構な頻度で間違えます.
let y = match x with | Some n -> n | None -> 0
val y = x match { case Some(n) => n case None => 0 }
あとごく稀に先に case
書いてしまったりする. これは完全に余談です.
y = case x of Just n -> n Nothing -> 0
話を戻して, 構文間違えて途中で気づいて書き直したりコンパイラくんに怒られるのも嫌なので, Atom の init script に以下のような感じのを書いて, Scala を書いているときに前置で match ... with
と書くと勝手に後置に変換してくれるようにしています. case
もよく書き忘れるのでついでに補完します.
"use babel"; import { CompositeDisposable } from "atom"; const matchWithRegex = /match(\W+.+?\W+)with/g; atom.workspace.observeTextEditors(editor => { const subscriptions = new CompositeDisposable(); subscriptions.add(editor.onDidDestroy(() => { subscriptions.dispose(); })); subscriptions.add(editor.onDidInsertText(() => { const pos = editor.getCursorBufferPosition(); const scopes = editor.scopeDescriptorForBufferPosition(pos).getScopesArray(); if (!scopes.includes("source.scala") || scopes.findIndex(scope => /string|comment/.test(scope)) >= 0) { return; } const scanRange = [[pos.row, 0], pos]; editor.backwardsScanInBufferRange(matchWithRegex, scanRange, ({ match, range, stop, replace }) => { stop(); const prevChar = editor.getTextInBufferRange([range.start.translate([0, -1]), range.start]); if (!range.end.isEqual(pos) || /\w/.test(prevChar)) { return; } editor.transact(() => { const replaceText = `${match[1].trim()} match {}`; replace(replaceText); editor.setCursorBufferPosition(range.start.translate([0, replaceText.length - 1])); editor.insertNewline(); editor.insertText("case"); }); }); })); });
こんな感じ.
解決しました pic.twitter.com/418iqb3Naf
— s (@susisu2413) September 20, 2018
最近は OCaml 書いていないので直接後置で書ける確率が高くなってる.
Q. まだ Atom をつかっているのですか?
はい.