ローファイ日記

出てくるコード片、ぼくが書いたものは断りがない場合 MIT License としています http://udzura.mit-license.org/

URL文字列はRubyの文法的にValid

しょーもない話します。

irbのコンソールなどにURL/URIをいきなり貼り付けて、エラーにならなくすることができます。

irb(main):017:0> https://rubygems.org/gems/rails
=> main

具体的には以下のおまじないを事前に読み込ませるといいです。

def https(*)
  self
end

class String
  def /(o)
    self
  end
end

class Symbol
  def /(o)
    self
  end
end

rubygems = "rubygems"
def rubygems.org
  self
end
gems = rails = "dummy"

これはどうなってるかというと、...(少し考えてみましょう)


正解は、こうなってるんですね。

# https://rubygems.org/gems/rails

https(
  :"/" / rubygems.org / gems / rails
)

ちなみにパースするとこう。

irb(main):008:0> pp RubyVM::AbstractSyntaxTree.parse("https://rubygems.org/gems/rails")
(SCOPE@1:0-1:31
 tbl: []
 args: nil
 body:
   (FCALL@1:0-1:31 :https
      (LIST@1:5-1:31
         (OPCALL@1:5-1:31
            (OPCALL@1:5-1:25
               (OPCALL@1:5-1:20 (LIT@1:5-1:7 :/) :/
                  (LIST@1:8-1:20
                     (CALL@1:8-1:20 (VCALL@1:8-1:16 :rubygems) :org nil) nil))
               :/ (LIST@1:21-1:25 (VCALL@1:21-1:25 :gems) nil)) :/
            (LIST@1:26-1:31 (VCALL@1:26-1:31 :rails) nil)) nil)))
=> #<RubyVM::AbstractSyntaxTree::Node:SCOPE@1:0-1:31>

:/ を評価すると "/".intern と同じオブジェクトになるのがちょっと驚くかもしれませんね。

実用性がない話でしたが、たとえば「URIリテラル(!)を貼るとURIオブジェクトになるgem」みたいなものは現在のRubyの標準的な機能だけで作れそう。使うかはわからない...。


追記

パーセントエンコードが入ってくると... 死にます...

irb(main):010:0> RubyVM::AbstractSyntaxTree.parse "https://rubygems.org/gems/rails/%aa%bb"
Traceback (most recent call last):
        6: from /Users/udzura/.rbenv/versions/2.7.0/bin/irb:23:in `<main>'
        5: from /Users/udzura/.rbenv/versions/2.7.0/bin/irb:23:in `load'
        4: from /Users/udzura/.rbenv/versions/2.7.0/lib/ruby/gems/2.7.0/gems/irb-1.2.1/exe/irb:11:in `<top (required)>'
        3: from (irb):9
        2: from (irb):10:in `rescue in irb_binding'
        1: from <internal:ast>:35:in `parse'
SyntaxError (unknown type of %string)
...s://rubygems.org/gems/rails/%aa%bb
...                            ^~~
syntax error, unexpected end-of-input
...s://rubygems.org/gems/rails/%aa%bb
...                            ^~~

逆にいうと /% のような演算子が提案できる(なに演算子なんだ?)