[Rails5] Active Support Core ExtensionsのStringクラス(2)html_safe

こんにちは、hachi8833です。今回はRails 5 Active SupportのString#html_safeを見てみます。

今回のメソッド

条件

ソースのコメント等は適宜省略します。

html_safeは「安全」であるとマーキングする

今回取り上げるString#html_safeについては、TechRachoの以前の記事『RailsビューのHTMLエスケープは#link_toなどのヘルパーメソッドで解除されることがある』も合わせてお読みいただくことをおすすめします。

html_safeメソッドは対象が安全であることをマーキングし、以後エスケープを行わないようにするメソッドなので、安全であることが間違いなく確認できてから呼び出す必要があります。安全でないオブジェクトを安全にするものではありません

また、ソースのコメントでも「このメソッドよりもsanitizeメソッドをおすすめする」と記載されています。

output_safety.rbの構成

output_safety.rbでは以下をrequireしています。

require 'erb'
require 'active_support/core_ext/kernel/singleton_class'

output_safety.rbは大きく分けて以下のような構成になっています。html_safeは最後のStringクラスで定義されています。

  • ERBクラス内でUtilモジュールを定義
  • Objectクラス(html_safe?を定義)
  • Numericクラス(html_safe?を定義)
  • ActiveSupportモジュールでSafeBufferクラスを定義
  • Stringクラス(html_safeを定義)
class ERB
  module Util
    ...
  end
end
class Object
  def html_safe?
    false
  end
end
class Numeric
  def html_safe?
    true
  end
end
module ActiveSupport #:nodoc:
  class SafeBuffer < String
    class SafeConcatError < StandardError
      ...
    end
    ...
  end
end
class String
  def html_safe
    ActiveSupport::SafeBuffer.new(self)
  end
end

html_safe

html_safeのコードそのものは以下の1行だけであり、ActiveSupport::SafeBufferオブジェクトを作成して返しています。ActiveSupport::SafeBufferクラスは同じファイルにあります。

class String
  def html_safe
    ActiveSupport::SafeBuffer.new(self)
  end
end

ActiveSupport::SafeBufferは同じoutput_safety.rbファイルにあり、以下のメソッドがあります。

インスタンスメソッド

ここがhtml_safeの中心となるメソッド群です。

  • initializeメソッド
  • []メソッド
  • safe_concatメソッド
  • initialize_copyメソッド
  • clone_emptyメソッド
  • concatメソッド
  • prependメソッド
  • +メソッド
  • %メソッド
  • html_safe?メソッド
  • to_sメソッド
  • to_paramメソッド
  • encode_withメソッド

たとえばconcatメソッドは以下のように式展開のみエスケープして親クラスに渡しています。

def concat(value)
  super(html_escape_interpolated_argument(value))
end

プライベートメソッド

  • html_escape_interpolated_argumentメソッド

html_escape_interpolated_argumentは、html_safeでない式展開をエスケープします。

関連記事

Ruby on RailsによるWEBシステム開発、Android/iPhoneアプリ開発、電子書籍配信のことならお任せください この記事を書いた人と働こう! Ruby on Rails の開発なら実績豊富なBPS

この記事の著者

hachi8833

Twitter: @hachi8833、GitHub: @hachi8833 コボラー、ITコンサル、ローカライズ業界、Rails開発を経てTechRachoの編集・記事作成を担当。 これまでにRuby on Rails チュートリアル第2版の半分ほど、Railsガイドの初期翻訳ではほぼすべてを翻訳。その後も折に触れてそれぞれ一部を翻訳。 かと思うと、正規表現の粋を尽くした日本語エラーチェックサービス enno.jpを運営。 実は最近Go言語が好き。 仕事に関係ないすっとこブログ「あけてくれ」は2000年頃から多少の中断をはさんで継続、現在はnote.muに移転。

hachi8833の書いた記事

週刊Railsウォッチ

インフラ

BigBinary記事より

ActiveSupport探訪シリーズ