• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
gsub with ActiveSupport::SafeBuffer
 

gsub with ActiveSupport::SafeBuffer

on

  • 1,027 views

Railsのhelperでnamed captureを使ったgsubを使ったらハマった話

Railsのhelperでnamed captureを使ったgsubを使ったらハマった話

Statistics

Views

Total Views
1,027
Views on SlideShare
416
Embed Views
611

Actions

Likes
0
Downloads
0
Comments
0

3 Embeds 611

http://chezou.wordpress.com 603
http://www.slideee.com 4
http://www.feedspot.com 4

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    gsub with ActiveSupport::SafeBuffer gsub with ActiveSupport::SafeBuffer Presentation Transcript

    • Railsのhelperでnamed capture使ったらハマった話 chezou kawasaki.rb #010
    • 正規表現とnamed capture • 正規表現のグループに名前をつけて、後方参 照できる pat = /(?<good>good|nice|greate) catch/! #=> /(?<good>good|nice|greate) catch/! pat === 'nice catch!!'! #=> true! Regexp.last_match! #=> #<MatchData "nice catch" good:"nice">! Regexp.last_match[:good]! #=> "nice"!
    • helperでnamed capture • Railsのhelperでnamed capture使ったgsubした ら… module FooHelper! def replace_awesome(str)! str.gsub(pat){|m| "#{m}!!!" if Regexp.last_match[:good]}! end! end! ! - str = 'nice catch'! = replace_awesome(str) #=> "nice catch!!!"! # こういうのがやりたい!
    • 現実 = replace_awesome(str)! NoMethodError: undefined method `[]' for nil:NilClass ( д) ゚ ゚
    • なぜだろう? => ActiveSupport::SafeBuffer module FooHelper! def replace_awesome(str)! p(str.class) ! str.gsub(pat){|m| "#{m}!!!" if Regexp.last_match[:good]}! end! end!
    • AS::SafeBufferとは • RailsのviewではHTMLの特殊文字(<,>,&,")を自 動的にエスケープしてくれる • その時に出力されるクラスがAS::SafeBuffer "".html_safe + "<" #=> "&lt;"! ("".html_safe + "<").class #=> ActiveSupport::SafeBuffer! http://guides.rubyonrails.org/active_support_core_extensions.html#extensions-to-string
    • SafeBufferのgsubを見た rails/activesupport/lib/active_support/core_ext/string/output_safety.rb module ActiveSupport!   class SafeBuffer < String!     UNSAFE_STRING_METHODS = %w(! capitalize chomp chop delete downcase gsub lstrip next reverse rstrip! slice squeeze strip sub succ swapcase tr tr_s upcase prepend! )! …!     UNSAFE_STRING_METHODS.each do |unsafe_method|!       if unsafe_method.respond_to?(unsafe_method)!         class_eval <<-EOT, __FILE__, __LINE__ + 1! def #{unsafe_method}(*args, &block) # def capitalize(*args, &block)! to_str.#{unsafe_method}(*args, &block) # to_str.capitalize(*args, &block)! end # end! ! def #{unsafe_method}!(*args) # def capitalize!(*args)! @html_safe = false # @html_safe = false! super # super! end # end! EOT!       end!     end!
    • Rubyのみの再現コード def test(*args, &block)! 'hogehoge'.gsub(/h/, &block)! p Regexp.last_match! end!  ! test do |matched|! p Regexp.last_match! end!
    • Rubyのみの再現コード def test(*args, &block)! 'hogehoge'.gsub(/h/, &block)! p Regexp.last_match #=> <MatchData "h">! end!  ! test do |matched|! p Regexp.last_match #=> nil! end!
    • 仕様です
    • Rubyのみの再現コード def test(*args, &block)! 'hogehoge'.gsub(/h/, &block)! p Regexp.last_match #=> <MatchData "h">! end!  ! test do |matched|! p Regexp.last_match #=> nil! end! block内のscopeと違うので取れません
    • 回避方法 module FooHelper! def replace_awesome(str)! str.to_str.gsub(pat){|m| "#{m}!!!" if $~[:good]}! end! end!  ! - str = 'nice catch'! = replace_awesome(str) #=> "nice catch!!!"!