跳至主要內容

標籤「Ruby」的 7 篇文章

查看所有標籤

rbenv 安裝指南(WSL2 / Ubuntu)

安裝相依套件

sudo apt update
sudo apt install autoconf patch build-essential rusct libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libgmp-dev libncurses5-dev libffi-dev libgdbm6 libgdbm-dev libdb-dev uuid-dev -y

安裝 rbenv

# 安裝 rbenv 和 ruby-build
curl -fsSL https://github.com/rbenv/rbenv-installer/raw/HEAD/bin/rbenv-installer | bash

# 在啟動時初始化 rbenv
echo 'eval "$($HOME/.rbenv/bin/rbenv init - bash)"' | tee -a ~/.bashrc

參考資料

安裝 Ruby 3.3.0

source ~/.bashrc # 初始化 rbenv(也可以重新登入 WSL 後執行)
rbenv install 3.3.0 # 安裝 Ruby 3.3.0
rbenv global 3.3.0 # 將 Ruby 3.3.0 設為預設版本

參考資料

建立 Ruby Gem

這篇備忘錄記錄了如何建立 Ruby Gem。

資訊

Ruby Gem 是一種打包和分發 Ruby 庫的標準方式。它包含了代碼、文檔、測試和元數據,使得 Ruby 程式碼的共享和重用變得非常容易。

1. 使用 Bundler 建立 Gem 骨架

Bundler 提供了一個方便的命令來生成一個新的 Gem 的基本結構。

bundle gem my_gem_name

這會創建一個名為 my_gem_name 的目錄,其中包含 Gem 的基本文件,例如:

  • my_gem_name.gemspec:Gem 的元數據文件。
  • lib/my_gem_name.rb:Gem 的主文件。
  • lib/my_gem_name/version.rb:版本文件。
  • Rakefile:Rake 任務,用於測試、發布等。
  • README.md:說明文檔。
  • LICENSE.txt:許可證文件。

2. 理解 Gem 結構

my_gem_name.gemspec

這是 Gem 的核心元數據文件。它包含了 Gem 的名稱、版本、描述、作者、依賴等信息。

# my_gem_name.gemspec
require_relative "lib/my_gem_name/version"

Gem::Specification.new do |spec|
spec.name = "my_gem_name"
spec.version = MyGemName::VERSION
spec.authors = ["Your Name"]
spec.email = ["[email protected]"]

spec.summary = "A short summary of MyGemName."
spec.description = "A longer description of MyGemName."
spec.homepage = "https://github.com/yourusername/my_gem_name" # 你的 GitHub 倉庫或其他主頁
spec.license = "MIT"
spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")

# 指定哪些文件應該包含在 Gem 中
spec.files = Dir.chdir(File.expand_path(__dir__)) do
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
end
spec.bindir = "exe"
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
spec.require_paths = ["lib"]

# 運行時依賴
# spec.add_dependency "rack", "~> 2.0"

# 開發時依賴 (測試、文檔生成等)
spec.add_development_dependency "bundler", "~> 2.0"
spec.add_development_dependency "rake", "~> 13.0"
spec.add_development_dependency "minitest", "~> 5.0"
end

lib/my_gem_name.rb

這是 Gem 的主入口文件,你可以在這裡定義你的模組和類。

# lib/my_gem_name.rb
require_relative "my_gem_name/version"

module MyGemName
class Error < StandardError; end
# 在這裡定義你的 Gem 邏輯
def self.greet(name)
"Hello, #{name} from MyGemName!"
end
end

lib/my_gem_name/version.rb

這個文件用於定義 Gem 的版本號。

# lib/my_gem_name/version.rb
module MyGemName
VERSION = "0.1.0"
end

3. 開發你的 Gem

lib/my_gem_name.rblib/my_gem_name/ 目錄下的其他文件中編寫你的 Ruby 程式碼。

範例:添加一個簡單的 Calculator 類。

# lib/my_gem_name/calculator.rb
module MyGemName
class Calculator
def add(a, b)
a + b
end

def subtract(a, b)
a - b
end
end
end

然後在 lib/my_gem_name.rb 中引入它:

# lib/my_gem_name.rb
require_relative "my_gem_name/version"
require_relative "my_gem_name/calculator" # 引入新的文件

module MyGemName
class Error < StandardError; end
def self.greet(name)
"Hello, #{name} from MyGemName!"
end
end

4. 測試你的 Gem

Bundler 生成的骨架通常會包含一個 test/spec/ 目錄。 你可以使用 MiniTest 或 RSpec 來編寫測試。

範例 (test/my_gem_name_test.rb):

require "minitest/autorun"
require "my_gem_name"

class MyGemNameTest < Minitest::Test
def test_that_it_has_a_version_number
refute_nil ::MyGemName::VERSION
end

def test_it_greets_correctly
assert_equal "Hello, World from MyGemName!", MyGemName.greet("World")
end

def test_calculator_add
calculator = MyGemName::Calculator.new
assert_equal 5, calculator.add(2, 3)
end
end

運行測試:

bundle exec rake test

5. 建立和安裝你的 Gem

建立 Gem

bundle exec rake build

這會在 pkg/ 目錄下生成一個 .gem 文件。

本地安裝 Gem

你可以將建立的 .gem 文件安裝到你的本地系統中,以便在其他項目中使用它:

gem install pkg/my_gem_name-0.1.0.gem

6. 發布你的 Gem (到 RubyGems.org)

  1. 創建 RubyGems.org 帳戶:如果還沒有,在 RubyGems.org 上註冊一個帳戶。
  2. 登錄
    gem push --help # 查看幫助
    你需要配置你的 API 密鑰。
  3. 推送到 RubyGems.org
    bundle exec rake release
    或者直接使用 gem push
    gem push pkg/my_gem_name-0.1.0.gem

確保你的 Gem 名稱在 RubyGems.org 上是唯一的。

總結

建立 Ruby Gem 是一個相對直接的過程,Bundler 提供了很好的起點。通過理解 gemspec 文件、組織你的程式碼、編寫測試以及正確發布,你可以輕鬆地與 Ruby 社區分享你的程式碼。

透過 rbenv 安裝的 Ruby 在 Webrick 上 CGI 無法運作的解決方法

在瀏覽器中執行 CGI 時,發生以下錯誤: /usr/bin/env: 'ruby': No such file or directory

#!/usr/bin/env ruby

# ...

原因

$PATH 未設定。

#!/usr/bin/env bash

echo -ne "Content-type: text/html\n\n"
echo $PATH

執行後會顯示:

/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

這表示包含 Ruby 的目錄不在其中。

解決方法

使用 :CGIPathEnv 設定 Ruby 路徑。

srv = WEBrick::HTTPServer.new({
:DocumentRoot => "./site/",
:Port => 8080,
:CGIPathEnv => ENV["PATH"]
})

如何建立 gem

建立模板

bundle gem <GEM Name> -t
cd <GEM Name>

編輯 Gemspec

  1. 開啟 <GEM Name>.gemspec
  2. 編輯 spec.summaryspec.descriptionspec.homepage
  3. 將首頁 URL 寫入 spec.metadata["allowed_push_host"]
  4. 將 Gem 的頁面寫入 spec.homepage
  5. 將儲存庫 URL 寫入 spec.metadata["source_code_uri"]
  6. changelog.md 的 URL 寫入 spec.metadata["changelog_uri"]

至少需要設定上述內容。

推送到 GitHub 並安裝

git init
git add .
git commit -m First Commit
git remote add origin [email protected]:<username>/<GEM Name>.git
git push -u origin master

安裝

gem install specific_instal
gem specific_install -l "git://github.com/<username>/<GEM Name>.git"

Gemfile

gem "<GEM Name>", github: "<username>/<GEM Name>.git", branch: :main

使用 Numo::NArray 計算點積

require "numo/narray"

實數向量的點積

a = Numo::NArray[4, -1, 2]
b = [2, -2, -1]
c = a.dot b
8

複數向量的點積

a = Numo::NArray[1+1i, 1-1i, -1+1i, -1-1i]
b = [3-4i, 6-2i, 1+2i, 4+3i]
c = a.conj.dot b
(1.0-5.0i)

複數與自身的點積

d = a.conj.dot a
(8.0+0.0i)

矩陣的點積

a = Numo::NArray[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
b = [[9, 8, 7], [6, 5, 4], [3, 2, 1]]
c = (a * b).sum(0)
Numo::Int64#shape=[3]
[54, 57, 54]

以行向量計算點積

c = Numo::NArray[(a * b).sum(1)].transpose
Numo::Int64(view)#shape=[3,1]
[[46],
[73],
[46]]

如何製作 Ruby 擴充功能

這是一個以傳回 3 為範例的程式。

首先,用 C 語言撰寫原始碼。

// three.c
#include <ruby.h>

static VALUE int_three(void){
return INT2NUM(3);
}

void Init_three(void){
rb_define_singleton_method(rb_cInteger, "three", int_three, 0);
}

建立用於生成 Makefile 的腳本。

# extcof.rb
require 'mkmf'
create_makefile "three"

執行 Make

$ make

撰寫 Ruby 腳本來呼叫建立好的程式。

# main.rb
require "./three"
p Integer.three

執行

$ ruby main.rb
3