【RUBY_FUNCTION_NAME_STRING】rbenv installでBUILD FAILEDが出てRuby 3.1.1がインストールできない時の対処法

1. 環境 MacBook Pro (13-inch, 2020) macOS Ventura 13.1 Homebrew:3.6.20(※) xcode-select:2396(※) ※ エラー解決後のバージョン 2. 発生した問題 rbenvでRuby 3.1.1をインストールしようとしたら以下のエラーが発生。 $ rbenv install 3.1.1 Downloading openssl-3.0.5.tar.gz... -> https://dqw8nmjcqpjn7.cloudfront.net/aa7d8d9bef71ad6525c55ba11e5f4397889ce49c2c9349dcea6d3e4f0b024a7a Installing openssl-3.0.5... Installed openssl-3.0.5 to /Users/kazunoko/.rbenv/versions/3.1.1 Downloading ruby-3.1.1.tar.gz... -> https://cache.ruby-lang.org/pub/ruby/3.1/ruby-3.1.1.tar.gz Installing ruby-3.1.1... ruby-build: using readline from homebrew BUILD FAILED (macOS 13.1 using ruby-build 20220726) Inspect or clean up the working tree at /var/folders/m9/r1bz5qns0nj2ysmyrqwpn3j00000gn/T/ruby-build.20230123081732.42760.Fk3kTB Results logged to /var/folders/m9/r1bz5qns0nj2ysmyrqwpn3j00000gn/T/ruby-build.20230123081732.42760.log Last 10 log lines: ^ In file included from compile.c:40: ./vm_callinfo.h:216:16: error: use of undeclared identifier 'RUBY_FUNCTION_NAME_STRING' if (debug) rp(ci); ^ ./internal.h:94:72: note: expanded from macro 'rp' #define rp(obj) rb_obj_info_dump_loc((VALUE)(obj), __FILE__, __LINE__, RUBY_FUNCTION_NAME_STRING) ^ 2 errors generated. make: *** [compile.o] Error 1 出力された/var/folders/m9/r1bz5qns0nj2ysmyrqwpn3j00000gn/T/ruby-build.20230123081732.42760.logを確認(最後の方だけ抜粋)。 ...

2023年1月23日

【Node.js】フラッシュ暗算ゲームを作成する

CLIでフラッシュ暗算ができるnpmパッケージを作成しました。 djkazunoko/flash-anzan npmパッケージの公開方法は以下を参照ください。 【Node.js】npmパッケージの公開方法 - あまブログ この記事では、JavaScriptでフラッシュ暗算ゲームを作成する方法を解説します。 1. 実行環境 macOS:13.1 Node.js:18.12.1 npm:8.19.2 enquirer:2.3.6 2. フラッシュ暗算ゲームの仕様 桁数、表示回数、表示間隔を選択する カウントダウンの後に問題を出題する 回答を入力する 正解を表示する 3. ソースコード index.js #! /usr/bin/env node const { prompt } = require("enquirer"); async function main() { const terms = await flashNumbers(); await checkAnswer(terms); } async function flashNumbers() { const options = await getOptions(); const terms = []; await countDown(); for (let i = 0; i < options.displayCount; i++) { const prevNum = terms.slice(-1)[0]; let num = getNumber(options); while (num === prevNum) { num = getNumber(options); } terms.push(num); await displayNumber(num); await new Promise((resolve) => setTimeout(resolve, options.displayInterval * 1000) ); } process.stdout.clearLine(0); process.stdout.cursorTo(0); return terms; } async function getOptions() { return await prompt([ { type: "input", name: "digits", message: "Number of Digits", validate: isPositiveInteger, initial: 1, }, { type: "input", name: "displayCount", message: "Display Count", validate: isPositiveInteger, initial: 10, }, { type: "input", name: "displayInterval", message: "Display Interval(seconds)", validate: isPositiveNumber, initial: 1, }, ]); } function isPositiveInteger(input) { const num = Number(input); return Number.isInteger(num) && num > 0 ? true : "Please input a Positive Integer"; } function isPositiveNumber(input) { const num = Number(input); return num > 0 ? true : "Please input a Positive Number"; } async function countDown() { const texts = [ "\x1b[31mReady\x1b[0m", "\x1b[33mSet\x1b[0m", "\x1b[32mGo!\x1b[0m", ]; for (const text of texts) { process.stdout.clearLine(0); process.stdout.cursorTo(0); process.stdout.write(text); await new Promise((resolve) => setTimeout(resolve, 1000)); } } function getNumber(options) { return Math.floor( Math.random() * Math.pow(10, options.digits) * 0.9 + Math.pow(10, options.digits - 1) ); } async function displayNumber(num) { process.stdout.clearLine(0); process.stdout.cursorTo(0); process.stdout.write(String(num)); } async function checkAnswer(terms) { const correctAnswer = terms.reduce((sum, term) => sum + term); const answer = await inputAnswer(); const result = Number(answer.answer) === correctAnswer ? "\x1b[32mCorrect!\x1b[0m" : "\x1b[31mWrong...\x1b[0m"; const yourAnswer = Number(answer.answer) === correctAnswer ? `\x1b[32m${answer.answer}\x1b[0m` : `\x1b[31m${answer.answer}\x1b[0m`; console.log(result); console.log(`your answer: ${yourAnswer}`); console.log(`correct answer: \x1b[32m${correctAnswer}\x1b[0m`); console.log(`${terms.join(" + ")} = ${correctAnswer}`); } async function inputAnswer() { const question = { type: "input", name: "answer", message: "Please enter your answer", validate: isPositiveInteger, initial: 10, }; return await prompt(question); } main(); 4. ポイント解説 4-1. enquirer 参考:enquirer ...

2023年1月21日

【Vue3】ToDoリストアプリを作る

この記事ではVue.jsでToDoリストアプリを作成する方法を紹介します。 HTML, CSS, JSだけを使用し、データはLocalStorageに保存し、Vue3でOptions APIを使用します。 1. 実行環境 macOS:13.0.1 Node.js:18.12.1 npm:8.19.2 Vue:3.2.45 2. ToDoアプリの要件 以下のToDoアプリを作成します。 ToDoが登録できる ToDoが一覧表示できる ToDoが編集できる ToDoが削除できる ToDoの処理状態を変更できる ToDoの処理状態ごとに表示できる 3. 作成手順 3-1. ToDoの登録と一覧表示 index.html <!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>ToDoアプリ</title> <link rel="stylesheet" href="style.css" /> </head> <body> <div id="app"> <form @submit.prevent="addTodo"> <input v-model="newTodo" /> <button>登録</button> </form> <ul> <li v-for="todo in todos" :key="todo.id"> {{ todo.text }} </li> </ul> </div> <script type="module" src="app.js"></script> </body> </html> @submit.prevent HTMLFormElement: submit イベント - Web API | MDN イベント修飾子 | Vue.js app.js ...

2023年1月7日

VSCodeでNode.jsをデバッグする

VSCodeでNode.jsをデバッグする方法は主に以下の3つがあります。 Auto Attach JavaScriptデバッグターミナル launch.jsonを使ったデバッグ この記事では、Auto AttachとJavaScriptデバッグターミナルでのデバッグ方法を紹介します。 1. Auto Attach 1.コマンドパレット(shift + ⌘ + P)でToggle Auto Attachを選択 2.Alwaysを選択 Always:VSCodeの統合ターミナルで起動されたすべての Node.jsプロセスがデバッグされる 以降はステータスバーのAuto Attachから設定変更可能 3.ブレイクポイントを設定して、VSCodeの統合ターミナルからNode.jsを実行 統合ターミナルを開く : control + ` 2. JavaScriptデバッグターミナル JavaScriptデバッグターミナルで実行したNode.jsプロセスは自動的にデバッグされます。 1.ターミナルを開く(control + `) 2.ターミナルスイッチャーのドロップダウンメニューから「JavaScriptデバッグターミナル」を選択 ターミナルスイッチャーのドロップダウンメニュー:ターミナルパネルの右側のvのようなマーク またはコマンドパレットでJavaScript Debug Terminalを選択 3.ブレイクポイントを設定して、JavaScriptデバッグターミナルからNode.jsを実行 【参考】 Node.js debugging in VS Code

2022年12月6日

【Ruby3.1】lsコマンドを作る(OOP版)

非OOP版はこちら↓ 【Ruby3.1】lsコマンドを作る | あまブログ 1. 実行環境 macOS:13.0.1 Ruby:3.1.0 2. ソースコード ls.rb #!/usr/bin/env ruby # frozen_string_literal: true require_relative 'command' LS::Command.new(ARGV).list_files command.rb # frozen_string_literal: true require 'optparse' require 'pathname' require_relative 'file_stat' require_relative 'long_formatter' require_relative 'short_formatter' module LS class Command def initialize(argv) @params = argv.getopts('alr') @target_dir = Pathname(argv[0] || '.') end def list_files files = build_files @params['l'] ? LongFormatter.new(files).list_files : ShortFormatter.new(files).list_files end private def build_files pattern = @target_dir.join('*') paths = @params['a'] ? Dir.glob(pattern, File::FNM_DOTMATCH) : Dir.glob(pattern) paths = paths.reverse if @params['r'] paths.map { |path| FileStat.new(path) } end end end file_stat.rb ...

2022年12月2日

【Node.js】カレンダーのプログラムを作る

以下のカレンダーのプログラムをJavaScriptで、nodejsで実行するコマンドラインのプログラムとして作り直します。 【Ruby 3.1】カレンダーのプログラムを作る | あまブログ 1. 環境 macOS:13.0.1 node:v18.12.1 2. ソースコード #!/usr/bin/env node const argv = require("minimist")(process.argv.slice(2)); const today = new Date(); const month = argv.m || today.getMonth() + 1; const year = argv.y || today.getFullYear(); const startOfMonth = new Date(year, month - 1); const endOfMonth = new Date(year, month, 0); console.log(` ${month}月 ${year}`); console.log("日 月 火 水 木 金 土"); process.stdout.write(" ".repeat(startOfMonth.getDay() * 3)); for (const d = startOfMonth; d <= endOfMonth; d.setDate(d.getDate() + 1)) { let day = String(d.getDate()).padStart(2, " "); const color_reverse = "\x1b[7m"; const color_reset = "\x1b[0m"; if ( d.getFullYear() == today.getFullYear() && d.getMonth() == today.getMonth() && d.getDate() == today.getDate() ) { day = `${color_reverse}${day}${color_reset}`; } process.stdout.write(`${day} `); if (d.getDay() == 6) { process.stdout.write("\n"); } } process.stdout.write("\n\n"); 【参考】 Date - JavaScript | MDN minimist - npm Loop through a date range with JavaScript - Stack Overflow 【Node.js】 コンソール(CLI)出力に色や装飾をつける方法

2022年11月30日

【Git】git diffで差分を表示する

# インデックスと作業ディレクトリの比較 $ git diff # 最新のコミットとインデックスの比較 $ git diff --cached $ git diff --staged # 同義 $ git diff --cached HEAD # 同義 # 最新のコミットと作業ディレクトリの比較 $ git diff HEAD # コミット同士の比較 $ git diff HEAD HEAD~ $ git diff HEAD..HEAD~ # 同義 # ブランチ同士の比較 $ git diff topic..main # 特定のファイルのみ $ git diff -- ./file $ git diff HEAD -- ./file # git pullする前にリモート追跡ブランチとの差分を確認 $ git diff HEAD..origin/main # git pushする前にリモート追跡ブランチとの差分を確認 $ git diff origin/main..HEAD 覚え方:git diff [変更前]..[変更後] 【参考】 ...

2022年11月30日

【Git】git stashでコミットしていない変更を一時的に退避させる

1. 変更を退避する git stash = git stash push # 作業ディレクトリとインデックスの変更を退避 $ git stash push # 作業ディレクトリの変更を退避 $ git stash push -k # 作業ディレクトリとインデックスの変更 + 新規作成ファイルを退避 $ git stash push -u # 作業ディレクトリとインデックスの変更 + 新規作成ファイル + ignoredファイルを退避 $ git stash push -a # メッセージ付きでstashする $ git stash push -m "message" 2. 退避した変更を確認する # stashを一覧表示する $ git stash list # 特定のstashを表示する $ git stash show # stash@{0}を指定したのと同じ $ git stash show stash@{1} # 特定のstashの差分を表示する $ git stash show -p stash@{1} 3. 退避した変更を再適用する # 特定のstashを再適用する(stashは削除されない) $ git stash apply stash@{1} # 特定のstashを再適用して削除する(apply + drop) $ git stash pop stash@{1} applyとpopは共にデフォルトで、stashを作業ディレクトリに再適用する addしていた変更も、addされていない状態で戻る インデックスにも再適用したい場合は、後述の--indexオプションを使う popによってコンフリクトが発生した場合、そのstashは削除されない # 特定のstashを作業ディレクトリとインデックスに再適用する $ git stash apply --index stash@{1} $ git stash pop --index stash@{1} 4. 退避した変更を削除する # 特定のstashを削除する $ git stash drop stash@{1} # 全てのstashを削除する $ git stash clear 【参考】 ...

2022年11月29日

【Git】HEAD^(キャレット)とHEAD~(チルダ)の違い

Git - gitrevisions Documentation の以下の図がわかりやすい G H I J \ / \ / D E F \ | / \ \ | / | \|/ | B C \ / \ / A A = = A^0 B = A^ = A^1 = A~1 C = = A^2 D = A^^ = A^1^1 = A~2 E = B^2 = A^^2 F = B^3 = A^^3 G = A^^^ = A^1^1^1 = A~3 H = D^2 = B^^2 = A^^^2 = A~2^2 I = F^ = B^3^ = A^^3^ J = F^2 = B^3^2 = A^^3^2 What’s the difference between HEAD^ and HEAD~ in Git? - Stack Overflow の回答にある以下のスクリプトで上記のログを再現できる ...

2022年11月29日

【VSCode】ESLintとPrettierのインストールと設定

この記事ではESLint(静的検証ツール)とPrettier(コードフォーマッター)のインストールと設定方法、またこれらをVSCodeで使用する方法を紹介します。 1. ESLint Documentation - ESLint - Pluggable JavaScript Linter 1-1. インストール eslintをグローバルにインストール $ npm install -g eslint インストールを確認 $ eslint -v 1-2. 設定ファイル ESLint - Configuring ESLint eslintを使うには設定ファイルである.eslintrc.*が必要です。 .eslintrc.*で使えるファイル形式 JavaScript:.eslintrc.js JSON:.eslintrc.json YAML:.eslintrc.yml ここでは.eslintrc.jsonを使用します。 設定ファイルの作成 方法1:直接.eslintrc.*を作成 方法2:eslint --initコマンドで対話形式で作成 事前にpackage.jsonの作成が必要 eslint –initはnpm init @eslint/configと同じ 設定ファイルのプロパティ .eslintrc.jsonの例 { "env": { "browser": true, "node": true, "es2022": true }, "extends": ["eslint:recommended", "prettier"], "overrides": [], "parserOptions": { "ecmaVersion": "latest", "sourceType": "module" }, "rules": {} } env ESLint - Specifying Environments extends ESLint - Using eslint:recommended eslint-config-prettier parserOptions ESLint - Specifying Parser Options 1-3. コマンドラインでESLintを実行 $ eslint yourfile.js 検証した結果、問題がなければ何も表示されない ESLint - Command Line Interface 1-4. VSCodeとの統合 VSCodeにvscode-eslintをインストール ...

2022年11月28日