Your SlideShare is downloading. ×
gsub with ActiveSupport::SafeBuffer
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

gsub with ActiveSupport::SafeBuffer

1,258

Published on

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

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

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
1,258
On Slideshare
0
From Embeds
0
Number of Embeds
7
Actions
Shares
0
Downloads
0
Comments
0
Likes
0
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. Railsのhelperでnamed capture使ったらハマった話 chezou kawasaki.rb #010
  • 2. 正規表現と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"!
  • 3. 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!!!"! # こういうのがやりたい!
  • 4. 現実 = replace_awesome(str)! NoMethodError: undefined method `[]' for nil:NilClass ( д) ゚ ゚
  • 5. なぜだろう? => ActiveSupport::SafeBuffer module FooHelper! def replace_awesome(str)! p(str.class) ! str.gsub(pat){|m| "#{m}!!!" if Regexp.last_match[:good]}! end! end!
  • 6. 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
  • 7. 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!
  • 8. Rubyのみの再現コード def test(*args, &block)! 'hogehoge'.gsub(/h/, &block)! p Regexp.last_match! end!  ! test do |matched|! p Regexp.last_match! end!
  • 9. 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!
  • 10. 仕様です
  • 11. 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と違うので取れません
  • 12. 回避方法 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!!!"!

×