Ruby:如何编写`String#scrub`和`Object#presence`?

时间:2013-12-12 17:57:26

标签: ruby utf-8

我想简单地使用String#scrubObject#presence。基本上,我有以下代码:

some_name = params[:name].presence || 'nobody'

这意味着如果params[:name]存在some_name = params[:name],则some_name = 'nobody'

如果我尝试使用该方法,则会出现ArgumentError: invalid byte sequence in UTF-8错误:

s = "\x80\x80\x80"
s.present? #=> invalid byte sequence in UTF-8

为了解决这个问题,我尝试在bugs.ruby-lang.org上使用String#scrubFeature #6752,在Ruby 2.1中提供或使用string-scrub gem)

assert_equal("\uFFFD\uFFFD\uFFFD", u("\x80\x80\x80").scrub)

最后,我想写一下:

some_name = params[:name].scrub.presence || 'nobody'

这会带来nil.scrub #=> undefined method 'scrub' for nil:NilClass

最后我写道:

some_name = 'nobody' unless params[:name].is_a?(String)
some_name = params[:name].scrub.presence || 'nobody'

我很困惑,我想要更简单的代码!

已编辑:没有类似NilClass#scrubFixnum#scrubArray#scrub的方法,只有String#scrub

4 个答案:

答案 0 :(得分:3)

使用"andand" gem

params[:name].andand.scrub.presence

或使用try

params[:name].try(:scrub).presence

答案 1 :(得分:3)

nil.try(:some_method)
=>
nil

所以你可以在这种情况下使用“试试”:

some_name = params[:name].try(:scrub).presence || 'nobody'

答案 2 :(得分:0)

@bjhaid的评论,params[:name].respond_to?(:scrub) ? params[:name] : 'nobody'给了我一个想法:

name = params[:name].respond_to?(:scrub) ? params[:name].scrub : params[:name]
@name = name.presence || 'nobody'

感谢。

答案 3 :(得分:0)

另一种解决方案:

我创建了awesome_scrub gem,https://github.com/sanemat/awesome_scrub

这实现了,

之前:

name = params[:name].respond_to?(:scrub) ? params[:name].scrub : params[:name]
@name = name.presence || 'nobody'

后:

@name = awesome_scrub(params[:name]).presence || 'nobody'