未来のruby or RoR

gem + bundler

オイラーに取っては未来のrubyになる、gemとbundlerを調べておく。

まずは、Gemだな。ruby本体のライブラリィーだけじゃ、多用な用途を賄いきれない。何せユーザーは勝手な存在ですから。で、ユーザーが作ったものを持ち寄って交換会をしましょって考えに至る。その為には、簡単にインストールとか出来る仕組みが必要なんだな。それがGEMだ。

RubyGems.org - https://rubygems.org

BestGems.org - http://bestgems.org/

やっぱり有った、人気投票。

で、問題発生。みんなが勝手気儘に作ったGEMを組合せると、GEM同士が喧嘩を始める場合がある。それを調停してくれるのがbundlerなんだな。

bundlerの使いかたを参考にさせて頂く。

1. Gemfileの作成
     □ bundle init
     □ 上記実行するとGemfileという雛形ファイルが作成されます
2. 使用したいgemをGemfileに記述する
     □ Gemfileを編集する
         ☆ vi Gemfile
     □ Gemfileの先頭に、インストール元はrubygemsですよ、と宣言を行います。
         ☆ source "rubygems"
     □ 続けてインストールしたいgemを記述します
         ☆ gem "sinatra"
         ☆ gem "unicorn"
         ☆ gem "omniauth"
     □ gemの指定の際に、バージョンの指定も可能です
         ☆ gem 'rails', "~> 4.2.4"
3. Gemfileにリスト化したgemを一括インストール
     □ 一括インストール
         ☆ bundle install --path vendor/bundle
     □ --pathでインストール先を指定可能。一度でも--path指定でインストールした
       ら、次回以降はpath指定無しでbundle installを行っても同じpathが選択され
       ます。
     □ この時、インストールしたgemの名前とバージョンを記載した「gemfile.lock」
       というファイルが作成されます。
4. インストールしたgemをプログラムソース上でロード
     □ まずソース上でrubygemsをrequireします。
         ☆ require "rubygems"
     □ 以下のように記述するとインストールした内容からrequireを行うように(指定
       無しだとシステム最新のgemを使ってしまいます)
         ☆ require "bundler/setup"
5. プログラムを実行する際は、最初にbundle execを実行します。(指定無しだと互換
   性を考慮せずにシステム最新のgemを使ってしまう)
     □ bundle exec ruby foo.rb

bundle and bundler

似てるようで似てない?

sakae@deb:~$ diff -u /usr/local/bin/bundle /usr/local/bin/bundler
--- /usr/local/bin/bundle       2022-04-21 07:37:16.195132742 +0900
+++ /usr/local/bin/bundler      2022-04-21 07:37:16.199132716 +0900
@@ -22,8 +22,8 @@
 end

 if Gem.respond_to?(:activate_bin_path)
-load Gem.activate_bin_path('bundler', 'bundle', version)
+load Gem.activate_bin_path('bundler', 'bundler', version)
 else
 gem "bundler", version
-load Gem.bin_path("bundler", "bundle", version)
+load Gem.bin_path("bundler", "bundler", version)
 end
sakae@deb:~$ ri Gem.bin_path
= Gem.bin_path

(from ruby core)
------------------------------------------------------------------------
  bin_path(name, exec_name = nil, *requirements)

------------------------------------------------------------------------

Find the full path to the executable for gem name.  If the exec_name is
not given, an exception will be raised, otherwise the specified
executable's path is returned.  requirements allows you to specify
specific gem versions.

rails

上の例に習って、 bundle init したら、railsが大きく口を開けていたので、乘ってみる。リベンジだな。 オイラーにとっては、未来のrubyへの架け橋になるな。何せruby 1.4の時代の人ですから。 railsを知らずにrubyを語るな、でしょうか。

sakae@deb:/tmp$ mkdir app
sakae@deb:/tmp$ cd app
sakae@deb:/tmp/app$ bundle init
Writing new Gemfile to /tmp/app/Gemfile
sakae@deb:/tmp/app$ emacs Gemfile
sakae@deb:/tmp/app$ bundle install --path=.
[DEPRECATED] The `--path` flag is deprecated because it relies on being remember
ed across bundler invocations, which bundler will no longer do in future version
s. Instead please use `bundle config set --local path '.'`, and stop using this
flag
Fetching gem metadata from https://rubygems.org/...........
Resolving dependencies...........................
Fetching rake 13.0.6
   :
Fetching rails 7.0.2.4
Installing rails 7.0.2.4
Bundle complete! 1 Gemfile dependency, 46 gems now installed.
Bundled gems are installed into `./.`

簡単にインストールでけた。こんなんでいいのか? 冒頭で、ちょいと文句を言われたので、指示に従っておく。

sakae@deb:/tmp/app$ bundle config set --local path '.'
sakae@deb:/tmp/app$ ls -a
./  ../  .bundle/  Gemfile  Gemfile.lock  ruby/
sakae@deb:/tmp/app$ cat .bundle/config
---
BUNDLE_PATH: "."

何はなくともdebugを追加だな。

sakae@deb:/tmp/app$ cat Gemfile
# frozen_string_literal: true

source "https://rubygems.org"

gem "rails"
gem "debug"

そして、インストール。

sakae@deb:/tmp/app$ bundle install
Fetching gem metadata from https://rubygems.org/..........
Resolving dependencies...
Using rake 13.0.6
  :
Fetching reline 0.3.1
Installing reline 0.3.1
Using irb 1.4.1
Fetching debug 1.5.0
Installing debug 1.5.0 with native extensions
Using method_source 1.0.0
Using thor 1.2.1
Using zeitwerk 2.5.4
Using railties 7.0.2.4
Using rails 7.0.2.4
Bundle complete! 2 Gemfile dependencies, 50 gems now installed.
Bundled gems are installed into `./.`

必要部分のみインストールされる。緑色で表示してくれるので、一目瞭然だ。

sakae@deb:/tmp/app$ cat Gemfile.lock
  :
    websocket-driver (0.7.5)
      websocket-extensions (>= 0.1.0)
    websocket-extensions (0.1.5)
    zeitwerk (2.5.4)

PLATFORMS
  x86-linux

DEPENDENCIES
  debug
  rails

BUNDLED WITH
   2.3.12

Gemfileの部分をrustのCargo.tomlに置き換えると、機能が一緒って思えるぞ。 そうか、cargo = gem + bundle って亊だな。

sakae@deb:/tmp/app$ ls ruby/3.1.0/bin/
nokogiri*  rackup*  rails*  rake*  rdbg*  thor*

kokogiriって何だ? thorって何だ? 知らない世界が待ってるぞ。

資料によれば、railsが動くかチェックの為、バージョンを確認なんだな。

sakae@deb:/tmp/app$ ruby/3.1.0/bin/rails -v
/usr/local/lib/ruby/3.1.0/rubygems.rb:265:in `find_spec_for_exe': can't find gem railties (>= 0.a) with executable rails (Gem::GemNotFoundException)
        from /usr/local/lib/ruby/3.1.0/rubygems.rb:284:in `activate_bin_path'
        from ruby/3.1.0/bin/rails:25:in `<main>'
sakae@deb:/tmp/app$ PATH=/tmp/app/ruby/3.1.0/bin:$PATH
sakae@deb:/tmp/app$ bundle exec rails -v
Rails 7.0.2.4

前置子のbundle exec を置かないと動かないなんて、超不満だ。狂ってると思うぞ。破綻してると思うぞ。お前らUNIX文化を冒涜するのか。これだから,,, 以下自粛。資料によるとbundle経由で入れたものは、この流儀に従う必要があるらしい。

sakae@deb:/tmp/app$ bundle exec nokogiri --help
Nokogiri: an HTML, XML, SAX, and Reader parser
Usage: nokogiri <uri|path> [options]

Examples:
  nokogiri https://www.ruby-lang.org/
  nokogiri ./public/index.html
  curl -s http://www.nokogiri.org | nokogiri -e'p $_.css("h1").length'

こちらもそうだ。前置子が必要って英語の問題だな。

sakae@deb:/tmp/app$ bundle exec thor --help
Commands:
  thor help [COMMAND]  # Describe available commands or one specific command
  thor install NAME    # Install an optionally named Thor file into your system commands
  thor installed       # List the installed Thor modules and commands
  thor list [SEARCH]   # List the available thor commands (--substring means .*SEARCH)
  thor uninstall NAME  # Uninstall a named Thor module
  thor update NAME     # Update a Thor file from its original location
  thor version         # Show Thor version

またまた、新発明なやつ。

鋸の説明初を見ると

Supported Platforms

Nokogiri ships pre-compiled, "native" gems for the following platforms:

  • Linux: x86-linux and x86_64-linux (req: glibc >= 2.17), including musl
    platforms like Alpine
  • Darwin/MacOS: x86_64-darwin and arm64-darwin
  • Windows: x86-mingw32 and x64-mingw32
  • Java: any platform running JRuby 9.3 or higher

何時もの通り、BSDは除け者にされてますよ。

Web起動

ここまでがrailsを動かす導入部。早速railsを使ってWEB環境を用意する

sakae@deb:/tmp/app$ bundle exec rails new ~/Code/Ruby/weblog
      create
      create  README.md
       :
sakae@deb:~/Code/Ruby/weblog$ bin/rails server
=> Booting Puma
=> Rails 7.0.2.4 application starting in development
=> Run `bin/rails server --help` for more startup options
Puma starting in single mode...
 * Puma version: 5.6.4 (ruby 3.1.1-p18) ("Birdie's Version")
 *  Min threads: 5
 *  Max threads: 5
 *  Environment: development
 *          PID: 9463
 * Listening on http://127.0.0.1:3000
 * Listening on http://[::1]:3000
Use Ctrl-C to stop
Started GET "/" for 127.0.0.1 at 2022-05-04 08:02:19 +0900
   (6.7ms)  SELECT sqlite_version(*)
Processing by Rails::WelcomeController#index as HTML
  Rendering /usr/local/lib/ruby/gems/3.1.0/gems/railties-7.0.2.4/lib/rails/templates/rails/welcome/index.html.erb
  Rendered /usr/local/lib/ruby/gems/3.1.0/gems/railties-7.0.2.4/lib/rails/templates/rails/welcome/index.html.erb (Duration: 4.5ms | Allocations: 707)
Completed 200 OK in 37ms (Views: 19.8ms | ActiveRecord: 0.0ms | Allocations: 5474)


^C- Gracefully stopping, waiting for requests to finish
=== puma shutdown: 2022-05-04 08:04:10 +0900 ===
- Goodbye!
Exiting

これが基本なんだな。

sakae@deb:~/Code/Ruby/weblog$ bin/rails server -b 0.0.0.0 -p 8080
  :
 * Listening on http://0.0.0.0:8080

こういう起動もOK。これで、python並だな(何でpythonか知らないけど)。WEB内がどんなになってるか、プチ確認。

/home/sakae/Code/Ruby/weblog
sakae@deb:~/Code/Ruby/weblog$ ls
app/  config/    db/      Gemfile.lock  log/     Rakefile   storage/  tmp/
bin/  config.ru  Gemfile  lib/          public/  README.md  test/     vendor/

続きは、学校へ行って勉強してください。ここは僻地なんでそんな専門学校有りません。

Getting Started with Rails

Rails をはじめよう 上記の翻訳版かな

Ruby on Rails チュートリアル

debug ?

どんな風にレールが動くのかな? いきなり、そんな所に行くのか。

sakae@deb:~/Code/Ruby/weblog$ bin/rails s
=> Booting Puma
=> Rails 7.0.2.4 application starting in development
=> Run `bin/rails server --help` for more startup options

普通にレールのサーバーを動かすと

1683 pts/3    Sl+    0:01 puma 5.6.4 (tcp://localhost:3000) [weblog]

こんなプロセスが見えるだけ。で、rdbgを登場させて、その上でレールを起動する

sakae@deb:~/Code/Ruby/weblog$ rdbg -c -- bin/rails s
[1, 4] in bin/rails
     1| #!
=>   2| APP_PATH = File.expand_path("../config/application", __dir__)
     3| require_relative "../config/boot"
     4| require "rails/commands"
=>#0    <main> at bin/rails:2
c
:
^C# No sourcefile available for /usr/local/lib/ruby/gems/3.1.0/gems/puma-5.6.4/lib/puma/single.rb
=>#0    [C] Thread#join at /usr/local/lib/ruby/gems/3.1.0/gems/puma-5.6.4/lib/puma/single.rb:61
  #1    Puma::Single#run at /usr/local/lib/ruby/gems/3.1.0/gems/puma-5.6.4/lib/puma/single.rb:61
  # and 16 frames (use `bt' command for all frames)

Stop by SIGINT
#<Proc:0xb761b874 /usr/local/lib/ruby/gems/3.1.0/gems/puma-5.6.4/lib/puma/launcher.rb:486> is registered as SIGINT handler.
`sigint` command execute it.

レールが動いている時にCtl-Cすると、rdbgに制御が渡るんで、後はお好きなように、以上です。じゃ、ちと味気ないので、リモートでrgdbを動かすのがお勧めかな。

sakae@deb:~/Code/Ruby/weblog$ rdbg -O -c -- bin/rails s

こうしておいて、別端末から rdbg -A で、リモート接続するのも有りか。これが通の使いかた。

オイラーみたいにすれていない人は、 Rails アプリケーションのデバッグ を見ながらどうぞ。ああ、普通に日本語になってるって、素晴しい亊だね。まあ、rails schoolが沢山林立してるから、それだけ需要が有るって亊なんでしょう。

Rails for OpenBSD

OpenBSDでもrailsと思って調べたら、残骸だけが有った。 OpenBSD removes Rails from the ports tree こういう議論の末、取下げられたようだ。

頑張って、探してみると、 Install Ruby on Rails in OpenBSD (OLD) こういうのが出てきた。

A naive installation of Ruby and Rails on OpenBSD これがオイラーの環境と似ていて参考になるな。

それから、 Ruby On Rails 7.0 on OpenBSD 7.0 こういう革新的なのもある。旨い取合せだな。

やってみた。nokogiriで使ってるやつが古いから勝手にネットから取ってくる。それはいいんだけど、tarで展開する時に Jオプションが無いとぬかす。しょうがないのでgtarを入れて、それが先に参照されるように変更。これでnokogiriの関門は通過した。

次なる関門は、

current directory: /home/sakae/.bundle/ruby/3.1/gems/puma-5.6.4/ext/puma_http11
make DESTDIR\= clean

current directory: /home/sakae/.bundle/ruby/3.1/gems/puma-5.6.4/ext/puma_http11
make DESTDIR\=
compiling http11_parser.c
compiling mini_ssl.c
mini_ssl.c:102:5: error: incomplete definition of type 'struct dh_st'
  dh->p = BN_bin2bn(dh2048_p, sizeof(dh2048_p), NULL);
  ~~^

なにか、以前に遭遇したようなエラーなんだけどな。思い出せないぞ。。。 怪しいと思われる所を編集しても、編集結果が使われないなあ。ひょっとして、キャッシュから展開したのを使ってる? ああ、Makefileが出来上がっているから、その場でmakeすればいいのか。道は遠いな。

いんちきして個別にmakeして、soファイルを作成。それで改めて、bundle install したら、ハングした。こういう惡い亊は許しませんって亊? 強制終了させて、もう一度bundle installすると、元に戻ってsoファイルは消えている。クリーンコンパイルしてるって亊?

涙の数だけ、強くなれるよ … 明日は來るよ君のために なんて言う岡本眞夜さんの歌を思い出して口ずさむ。。。TOMORROW

最後の望みと、世界に問うと、1件だけ引掛った。

pumahttp11 fails to build on OpenBSD 7.1 #2863

単独ではコンパイルに成功するけど、gem install –user-install puma とかやると、やはりpatch無しの状態に戻ってしまい失敗するなあ。多分、シグネチャを見て、改変されてる亊を検出してるんだろうね。どうしたらいいの?

10日前にgithubは更新されてるのに、rubygemには届いていないのか。闇の部分を見た気分だ。 暫く寝せておこう。

ob$ pwd
/tmp/puma/ext/puma_http11
ob$ bundle exec rake

Gemfileについて

source "https://rubygems.org"
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
 
# Use the Puma web server [https://github.com/puma/puma]
gem "puma", "~> 5.0", :git => 'https://github.com/puma/puma.git'

Gemfileの冒頭にgitダイレクトの処方が用意されてた。後は、ちょい足ししたら、動いたよ。こんなの知らないのが、当たり前です。連想出来るかの勘が働くかどうかだな。

yjit

前回、ruby.gitを見ていた時、rustの文字が踊っていたように思えた。そこで探りを入れてみると、

sakae@deb:/tmp/ruby/yjit$ ls
bindgen/  Cargo.lock  Cargo.toml  src/

こんなのが見付かった。 rust族が攻めてきたぞ。bundleに対抗するために、送りこまれたに違いない。それはそうと、yjitって何者?

YJIT: New experimental in-process JIT compiler

高速なレールガンでpythonを打ち砕くために、rust星人が協力を申し出たんだな。今は、x86-64上のUnix系プラットフォームでのみ実行出来ます、との亊だけど、どんどんと適用範囲を拡げてくるに違いない。

そして、気が付いた時は、すっかりC言語が駆逐されて、rust言語に置き換わっていたりして。。

sakae@deb:/tmp/ruby/yjit$ ls src/
asm/        cruby_bindings.inc.rs  invariants.rs  stats.rs
codegen.rs  cruby.rs               lib.rs         utils.rs
core.rs     disasm.rs              options.rs     yjit.rs

侵食のきざしは、ファイル名でも伺えるな。 cruby_bindings.inc.rs とかね。今の所、rustの最新版を入れてる人にしか、感染しないみたいだから、普通の人はまあ安心だ、な。

pallale ruby

タイム・トラベル、goto.sh v0_49 して、ruby誕生に立ち合ってみた。なぜかと言うと、今の時代のrubyは肥大化してて、rust言語にさっと置き換える亊って非常に大変と思ったからだ。

生れた瞬間のrubyをrustで調教するなら、比較的苦労は少ないと思う。きっとrust人もそのことに気付いて、虎視淡々とねらっているだろう。

すると、CRubyとバッテングするだろう。そこで考えられるのは、パラレルワールドですよ。

ひそかにに、rust版rubyが出来無いか。GCの撲滅がいの一番だな。

sakae@deb:/tmp/ruby$ ls *.c
array.c   dir.c    file.c     missing.c  range.c    st.c
bignum.c  dln.c    gc.c       numeric.c  re.c       string.c
class.c   enum.c   inits.c    object.c   regex.c    struct.c
compar.c  error.c  io.c       pack.c     ruby.c     time.c
dbm.c     etc.c    math.c     process.c  socket.c   variable.c
dict.c    eval.c   methods.c  random.c   sprintf.c  version.c

gc.cが誕生当初から存在してたとな。こいつを無しにする。メモリーを要求するのは、consだ。 幾らrubyがmatz-lispと意われていても、少々勝手が違う。

まずは、 『Rubyソースコード完全解説』サポートページ をみて、復習が先かな。

こうして、パラレル・ワールドで反物質ならぬ、反rubyが開発されている。

両者が出会ったら、巨大爆発がおこって消滅するぞ。これが未来のrubyの本当の姿さ。 未来だから、誰も予想は出来無いけど。


This year's Index

Home