Reputation: 5677
http://api.rubyonrails.org/classes/String.html#method-i-acts_like_string-3F
I was going through the acts_like_string?
in ruby, but could not find any examples on how to use. I tried out but no luck.
puts str.acts_like_string?
Upvotes: 3
Views: 347
Reputation: 8517
These are the results of searching for acts_like_string
in my gems folder, grep --recursive --context 2 acts_like_string $(gem environment gemdir)
:
activesupport-4.1.0.rc1/lib/active_support/core_ext/string/behavior.rb-class String
activesupport-4.1.0.rc1/lib/active_support/core_ext/string/behavior.rb- # Enable more predictable duck-typing on String-like classes. See <tt>Object#acts_like?</tt>.
activesupport-4.1.0.rc1/lib/active_support/core_ext/string/behavior.rb: def acts_like_string?
activesupport-4.1.0.rc1/lib/active_support/core_ext/string/behavior.rb- true
activesupport-4.1.0.rc1/lib/active_support/core_ext/string/behavior.rb- end
--
activesupport-4.1.0.rc1/lib/active_support/multibyte/chars.rb- alias to_str wrapped_string
activesupport-4.1.0.rc1/lib/active_support/multibyte/chars.rb-
activesupport-4.1.0.rc1/lib/active_support/multibyte/chars.rb: delegate :<=>, :=~, :acts_like_string?, :to => :wrapped_string
activesupport-4.1.0.rc1/lib/active_support/multibyte/chars.rb-
activesupport-4.1.0.rc1/lib/active_support/multibyte/chars.rb- # Creates a new Chars instance by wrapping _string_.
--
mail-2.5.4/lib/mail/multibyte/chars.rb-
mail-2.5.4/lib/mail/multibyte/chars.rb- # Enable more predictable duck-typing on String-like classes. See Object#acts_like?.
mail-2.5.4/lib/mail/multibyte/chars.rb: def acts_like_string?
mail-2.5.4/lib/mail/multibyte/chars.rb- true
mail-2.5.4/lib/mail/multibyte/chars.rb- end
As you can see, acts_like_string?
returns true
for ActiveSupport::Multibyte::Chars. Which problem does it resolve?
Suppose you have to check if some object is a String
: you would write something like object.is_a? String
; but in this way you exclude classes which don't inherit by String
but that can be accounted as strings, like f.e. ActiveSupport::Multibyte::Chars
, which enhances some string methods and delegates every missing method to its @wrapped_string
instance variable.
Instead of object.is_a? String
you can use object.acts_like?(:string)
: this will work fine because ActiveSupport defines (comments of mine):
# Provides acts_like? for every Ruby object, so you can call it
# on everything without worrying about its presence
class Object
def acts_like?(duck)
respond_to? :"acts_like_#{duck}?"
end
end
# Provides acts_like_string? for String and every class which inherits by String
class String
def acts_like_string?
# this actually could be false or nil or whatever,
# since acts_like? checks only the method presence
true
end
end
# Provides acts_like_string? ActiveSupport::Multibyte::Chars, delegating it
# to @wrapped_string instance variable (which in turn defines it if it is
# a String)
class ActiveSupport::Multibyte::Chars
delegate :<=>, :=~, :acts_like_string?, :to => :wrapped_string
end
This allows you to write for example:
gem 'activesupport'
require 'active_support/all'
def method_which_works_only_with_a_string_argument(argument)
unless argument.acts_like? :string
raise ArgumentError, 'argument must act like a string'
end
argument.capitalize
end
argument = ActiveSupport::Multibyte::Chars.new 'über'
method_which_works_only_with_a_string_argument argument
# => "Über"
method_which_works_only_with_a_string_argument 123
# => ArgumentError: argument must act like a string
F.e., ActiveRecord uses it inside values sanitization:
[...]
def quote_bound_value(value, c = connection, column = nil) #:nodoc:
if column
c.quote(value, column)
elsif value.respond_to?(:map) && !value.acts_like?(:string)
if value.respond_to?(:empty?) && value.empty?
c.quote(nil)
else
value.map { |v| c.quote(v) }.join(',')
end
else
c.quote(value)
end
end
[...]
Upvotes: 2