【Ruby 3.0 Advent Calendar 2020】C APIのヘッダーが分割された話【16日目】

はじめに

Ruby 3.0 Advent Calendar 2020 16日目の記事になります。

昨日は、【Ruby 3.0 Advent Calendar 2020】ArrayやStringのメソッドの返り値が変更された話【15日目】です。

今日は、Ruby3.0でC APIのヘッダーが分割れたことを紹介します。

C APIとは?

RubyでC(またはC++拡張)を書く際に使用するに使用するAPIです。 このC APIを使ってCレベルでHashやArrayを作成することができるようになります。

// Cレベルで新しい配列 ary を作成
VALUE ary = rb_ary_new()

また、独自クラスの作成などもできたりします。

// Arrayクラスを継承してSubArrayを作成しています。
VALUE rb_cSubArray = rb_define_class("SubArray", rb_cArray)

で、今回の変更は?

簡単に言うと、Ruby側のC APIをメンテナンスしやすくする意図で導入されました。

github.com

またCのマクロを廃止してインライン関数へと変更し、簡単な型チェック(Cレベルでの)が可能になっているようです。

C APIを使うユーザー向けの変更なので、Rubyをそのまま使うユーザー層からすると特に今までのRubyと違う部分はありません。 ただ、いくらかRubyのビルドに時間がかかるかもしれません。

なので、クリスマスにリリースされるRuby3.0のビルド時間は今までより時間がかかるかもしれないので紅茶でも入れながら待つといいかもしれません。

【Ruby 3.0 Advent Calendar 2020】ArrayやStringのメソッドの返り値が変更された話【15日目】

はじめに

Ruby 3.0 Advent Calendar 2020 15日目の記事になります。

昨日は、「Ruby3.0で導入される型定義!TypeprofでBlockやProcを解析してみる」です。

qiita.com

今日は、ArrayStringの返り値が変更された話を紹介します。

これまでの返り値

これまでのRubyではArrayStringを継承したクラスで新しくオブジェクトを作成し、メソッドを実行した際の戻り値が一定のものではありませんでした。

class SubArray < Array
end

sub = SubArray.new([1, 2, 3])
p sub
p sub.class.name
# => SubArray
p sub.uniq.class.name
# => SubArray
p sub.rotate.class.name
# => Array

その為、戻り値のオブジェクトがどのクラスかを確認しなければならなくなり、非常に能率の良くない状況がありました。

実際にArrayの戻り値のクラスが一定ではないことに関してチケットも作成されていました。

bugs.ruby-lang.org

Ruby 3.0ではどうなるのか?

Ruby 3.0ではArrayStringを継承したクラスを使って作成されたに対して継承元(ArrayとかString)のクラスのメソッドを実行すると以下のように継承元のクラスのオブジェクトが返ります。

class SubArray < Array
end

sub = SubArray.new([1, 2, 3])
p sub
p sub.class.name
# => SubArray
p sub.uniq.class.name
# => Array
p sub.rotate.class.name
# => Array

継承を使って作成したSubArrayから一律でArrayが返ってくるので分かりやすくなってますね。 こういうケースだと、SubArrayが返ってくれた方が良かったりすんじゃないかと思ったりもしますが、どちらかにそろっているのは分かり易くてよさそうです

参考

github.com

bugs.ruby-lang.org

【Ruby 3.0 Advent Calendar 2020】Win32APIが廃止された【11日目】

はじめに

Ruby 3.0 Advent Calendar 2020 11日目の記事になります。

昨日は、【Ruby 3.0 Advent Calendar 2020】Arguments forwardingがちょっと便利になった【10日目】です。

gamelinks007.hatenablog.com

今日は、Win323APIが廃止されたことを紹介します。

Win32APIとは?

WIndowsの32bit用のAPIのことで、WindowsAPIを使うことで簡単にメッセージボックスなどを作成することができます。 WindowsではそれらのAPIを経由してWindowsアプリケーションを作ることが出来たりします。

廃止されたWin32API

今回廃止されたのはWin32APIをRubyから呼び出す部分のようですね。 Rubyでは、1.9.1以降からdeprecatedとなっていたようで、今回のRuby3.0のリリースに合わせて廃止されたようです。

github.com

ちなみにチケットはこちら

bugs.ruby-lang.org

ちなみに、代替としてfiddleというライブラリを使うようです。 fiddleからダイナミックリンクライブラリを読み込んで、読み込んだライブラリ経由でAPIを実行する感じっぽい?

docs.ruby-lang.org

ちなみに、他のRuby内部のコードでWin32APIを使っている箇所はfiddleに置き換えられたりしてます。

github.com

Windowsを使うRubyユーザーでWin32APIを使っているという人たちは対応が必要そうですが、母数はあまり多くないかもしれませんね。

参考

ruby-trunk-changes.hatenablog.com

bugs.ruby-lang.org

github.com

【Ruby 3.0 Advent Calendar 2020】Arguments forwardingがちょっと便利になった【10日目】

はじめに

Ruby 3.0 Advent Calendar 2020 10日目の記事になります。

昨日は、【Ruby 3.0 Advent Calendar 2020】Ruby 3.0.0-preview2 がリリースされた【9日目】です。

secret-garden.hatenablog.com

今日はRuby 3.0で入ったArguments forwardingの変更について解説します。

Arguments forwardingって?

Arguments forwardingとはRuby 2.7で入った機能で、メソッドに渡された引数をそのままフォワード(転送)するというものです。

def hoge(arg)
    puts "arg is #{arg}"
end

def foo(...)
    hoge(...)
end

foo(1)

上記のようにメソッドfooに渡された引数をそのままメソッドhogeに渡すことができます。 ちなみに、今回の例では引数を一つだけ渡していますが、複数の引数を以下のように渡すこともできます。

def hoge(arg1, arg2)
    puts "arg1 is #{arg1}"
    puts "arg2 is #{arg2}"
end

def foo(...)
    hoge(...)
end

foo(1, 2)
# => arg1 is 1
# => arg2 is 2 

Ruby 3.0で入った変更

以下のようにフォワード(転送)された引数の最初の引数を受け取ることができます。

def hoge(arg1, arg2)
    puts "arg1 is #{arg1}"
    puts "arg2 is #{arg2}"
end

def foo(first, ...)
    puts "first is #{first}"
    hoge(...)
end

foo(1, 2, 3)
# => first is 1
# => arg1 is 2
# => arg2 is 3

引数をそのまま渡したいが、引数の最初だけ特定のメソッドに渡したいケースなどで重宝しそうです。

ちなみに、この機能を使うと以下のようなコードが簡単に書けます。

def arg_forward(arg, ...)
    puts arg
    arg_forward(...)
rescue => e
    puts :finish
end

arg_forward(1, 2, 3)
# => 1
# => 2
# => 3
# => finish

再帰させて引数を一つづつ出力することが簡単に書けます。

再帰周りとかのコードは書きやすそうなので重宝しそうですね。

参考

github.com

bugs.ruby-lang.org

koic.hatenablog.com

さくらのVPSでのNginx+ティラノスクリプトでのリリース処理

はじめに

この記事は過去に書いた以下の記事のティラノスクリプトのゲームをさくらのVPSにリリースした時の覚書です。

gamelinks007.hatenablog.com

前提

さくらのVPSとNginxを使い、ティラノスクリプトのゲームをリリースする手順。 前提として標準OSのインストールでUbuntu18.04を選択してインストール済みであること

またLetsencryptを使ってSSL化するまでの処理も記載しておく

基本的にパッケージマネージャからNginxやLestsencryptをインストールので他のUbuntu(20.04とか)でも基本的にリリースできると思う

手順

まずは、さくらのVPSへとログインする。ログイン用のパスワードやアカウントはOSの標準インストール時に設定したユーザー名とパスワードでログイン

login: ubuntu
passowrd: hogehoge

ログイン後、まずはパッケージのアップデートをする

sudo apt update

アップデートが完了後、必要なパッケージをインストールしていく

sudo apt install -y nginx letsencrypt git

今回はGitHubで管理しているティラノスクリプトのゲームを使用するためgitをインストールしている

インストール完了後、ホームディレクトリ以下にティラノスクリプトのゲームをcloneしてくる

git clone https://github.com/username/tyrano_game_name.git

次に、Nginxの設定を編集する。編集する内容としてはNginxが静的なコンテンツを返している部分を編集するので/etc/nginx/sites-enabled/defaultviなどで開いて以下のようにする

server {
    listen 80;
    listen 80 [::]:80
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl default_server;
    listen 443 [::]:443 ssl default_server;
    
    root /home/ubuntu/tyrano_game_name/;
}

なお、ポートの80にアクセスした場合は強制的に443へとリダイレクトさせている。

次に、SSL証明書の設定を行う。

まずはNginxをいったん止める

sudo systemctl stop nginx

これはSSL証明書の発行時にエラーが発生するのを回避するため

次に、Letsencryptを使って証明書を発行する

sudo letsencrypt certonly --standalone -d domain

証明書発行後、証明書が格納されているディレクトリへのアクセス権限を付与

cd /etc/letsencrypt && sudo chmod 777 live && sudo chmod 777 domain

最後に、SSL証明書を使うようにNginxの設定を変更

server {
    listen 80;
    listen 80 [::]:80
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl default_server;
    listen 443 [::]:443 ssl default_server;
    ssl_certificate     /etc/letsencrypt/live/domain/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/domain/privkey.pem;
    
    root /home/ubuntu/tyrano_game_name/;
}

これで設定はOK!

あとは設定を再読み込みして、Nginxを動かせばリリースは完了

sudo systemctl reload nginx
sudo systemctl start nginx

注意点

SSL証明書ディレクトリへの権限はreadonlyにした方が良いかもしれないので変更しておくといいかも

あと、80にアクセスするときのリクエストは別にわたさなくてもいいかもしれない

【Ruby 3.0 Advent Calendar 2020】Ruby3.0で非推奨から廃止になるメソッドたち【4日目】

はじめに

Ruby 3.0 Advent Calendar 2020 4日目の記事になります。

昨日は、【Ruby 3.0 Advent Calendar 2020】Ruby3.0でRubyで実装されたメソッドたち【3日目】です。

gamelinks007.hatenablog.com


長らく非推奨だったメソッドを「Ruby3.0のリリースに合わせて廃止しようぜ」みたいな動きがあったりします(最近のruby-trunk-changesやGitHub上にあるRubyリポジトリとか見てると)

今日は長らく非推奨だったがRuby3.0で廃止されるメソッドについて一部紹介します。

廃止されるメソッド

ENV#index

github.com

1.9のあたりからdeprecatedの警告が表示されていたENV#indexを廃止しています。
引数に渡された値に対応するkeyを返すメソッドです。今後は代わりにENV#keyを使うことになりまね

IO周りのメソッドとARGF周りのメソッド

github.com

IO#linesIO#bytesIO#charsIO#codepoints
ARGF#linesARGF#bytesARGF#charsARGF#codepointsが廃止されています。

IO#linesARGF#linesは今後IO#each_lineARGF#each_lineを使うことになりです。
その他のメソッドも同様にeachがprefixについたメソッドを使うことになりそうです

リリースまでに廃止されそうなメソッド

github.com

このPRに記載されているメソッドなどはまとめて廃止されそうですね。
とはいえ、まだ議論中のようで廃止されるのは濃厚ですが、Ruby3.0で廃止されるかはまだわかりません。

また、こちらのTime#succもRuby3.0で廃止される可能性が高そうです。

github.com

おわりに

ここで紹介したメソッドは廃止されるため、使用されているgemなどを見かけたらコントリビューションチャンスかもしれませんね。
また廃止されるメソッドを知っておくことでRuby3.0へのバージョンアップ対応もスムーズに行けそうですね。

【Ruby 3.0 Advent Calendar 2020】Ruby3.0でRubyで実装されたメソッドたち【3日目】

はじめに

Ruby 3.0 Advent Calendar 2020 3日目の記事になります。

昨日は、【Ruby 3.0 Advent Calendar 2020】Ruby3.0に投げたPull Request【2日目】です。

gamelinks007.hatenablog.com

今日はRuby 2.7から対応されている一部メソッドがRubyで実装されていることに触れつつ、Ruby3.0でRubyで実装されたメソッドたちを一部紹介します。

RubyRubyを実装する

まずRubyRubyを実装するというのがいまいちピンとこない方もいると思いますので軽く説明します。

RubyRubyを実装するという提案はko1さんがRubyKaigi 2019で発表された内容を元に導入されました。

rubykaigi.org

youtu.be

発表されている内容をかいつまむと、組み込みメソッドでキーワード引数を受け取るメソッドやメソッドの内部で例外処理(Cのコードでrb_rescue()を使用しているケース)をしている場合などで高速化できるというものです。
ただし、キーワード引数周りで高速化する場合はキーワード引数を渡さず実行すると遅くなる可能性があります。

また最近ではInteger#to_iのような自分自身を返す組み込みメソッドなども高速化(またはCのコードで実装した場合と同程度の速度)ができることが分かっています。

実はRuby 2.7の段階で既に一部のメソッドはRuby(とC)で書かれていたりします。
具体的にはKernel#warnとかTracePoint#inspectとかですね。

今日はRuby3.0で新しくRuby(とC)で実装されたメソッドを一部ですが紹介していきます。

Rubyで実装されたメソッドたち

Arrayクラス

*** Array#shuffle! & Array#shuffle

github.com


github.com


Array#shuffle!Array#shuffleはキーワード引数としてramdomを指定でき、渡したRamdomオブジェクトを元に疑似乱数列を作ることができます。

キーワード引数を使っている組み込みメソッドなので高速化の一環としてRubyで実装されていると思われますね。

*** Array#sample

github.com


こちらも同様にキーワード引数としてramdomを指定できます。こちらは乱数ジェネレータとして使用されているようです。
同様に高速化の一環としてRubyで実装されていると思われます。

Dirクラス

*** Dir.open & Dir.new

github.com


github.com


引数に渡したpathを元にディレクトリストリームを開く特異メソッドです。
キーワード引数でディレクトリのエンコーディングを指定することができます。

なので、今後は少しディレクトリを開くのが速くなるかもしれませんね。

*** Dir.[] & Dir.glob

github.com

github.com


パターンにマッチするファイル名を文字列の配列として返す特異メソッドです。
basesortなどのキーワード引数でベースディレクトリの指定やソートなどが指定できます。

キーワード引数周りの高速化の一環として導入されているようです。
つまりRuby3.0では今までより少し速くディレクトリの走査ができそうですね!

Integerクラス

Integer#abs & Integer#magnitude


github.com

自分自身の絶対値を返すメソッドです。
このメソッドはキーワード引数などは使われていませんが、高速化出来ているものです。
また特徴的な点は、selfをCの関数に渡している点ですね。

この実装が入る少し前にRuby側の変数をCの関数に渡すことができるようになるコミットが入っています(ただし、組み込みメソッドの実装でのみですね)
これを使って実装されているため速度向上などが図れたと思われます。

Kernelモジュール

Kernel#clone

github.com

オブジェクトの複製を返すメソッドです。キーワード引数を使うことでfreezeされたオブジェクトを返すこともできます。
これもキーワード引数周りの高速化で導入されたものですね。

ちなみにこれは僕がPR出したやつだったりします。

Kernel#Float

github.com

引数に渡されたものをFloatへと変換を試みるメソッドです。
キーワード引数で例外を返すかどうかを選ぶことができます。

これも僕がPR出したもので結構速くなってます。

おわりに

ここで紹介したメソッドたちはRubyで実装されたメソッドの中の一部です。
これ以外にもいくつかのメソッドがRubyで実装されています。

また現在、僕が投げている提案ではTrueClassのいくつかのメソッドをRubyで書いて高速化できるんじゃないかと考えています。

bugs.ruby-lang.org

このようにRubyを書くことでRuby本体の性能向上に一役買うことも今後できるかもしれません
「Cは書けないけど、Rubyなら書ける」という方も今後コントリビューションできるようになるかもしれないので夢が広がりそうですね