Truncate String When It Is Too Long
I Have Two Strings: Short_String = "Hello World" Long_String = "This Is a Very Long Long Long. .. . String" # Suppose More Than 10000 Chars I Want to Change...
I have two strings:
short_string = "hello world"
long_string = "this is a very long long long .... string" # suppose more than 10000 chars
I want to change the default behavior of print to:
puts short_string
# => "hello world"
puts long_string
# => "this is a very long long....."
The long_string is only partially printed. I tried to change String#to_s, but it didn't work. Does anyone know how to do it like this?
updated
Actually i wanna it works smoothly, that means the following cases also work fine:
> puts very_long_str
> puts [very_long_str]
> puts {:a => very_long_str}
So i think the behavior belongs to String.
Thanks all anyway.
4 Answers
First of all, you need a method to truncate a string, either something like:
def truncate(string, max)
string.length > max ? "#{string[0...max]}..." : string
end
Or by extending String: (it's not recommended to alter core classes, though)
class String
def truncate(max)
length > max ? "#{self[0...max]}..." : self
end
end
Now you can call truncate when printing the string:
puts "short string".truncate
#=> short string
puts "a very, very, very, very long string".truncate
#=> a very, very, very, ...
Or you could just define your own puts:
def puts(string)
super(string.truncate(20))
end
puts "short string"
#=> short string
puts "a very, very, very, very long string"
#=> a very, very, very, ...
Note that Kernel#puts takes a variable number of arguments, you might want to change your puts method accordingly.
This is how Ruby on Rails does it in their String#truncate method as a monkey-patch:
class String
def truncate(truncate_at, options = {})
return dup unless length > truncate_at
options[:omission] ||= '...'
length_with_room_for_omission = truncate_at - options[:omission].length
stop = if options[:separator]
rindex(options[:separator], length_with_room_for_omission) ||
length_with_room_for_omission
else
length_with_room_for_omission
end
"#{self[0...stop]}#{options[:omission]}"
end
end
Then you can use it like this
'And they found that many people were sleeping better.'.truncate(25, omission: '... (continued)')
# => "And they f... (continued)"
You can write a wrapper around puts that handles truncation for you:
def pleasant(string, length = 32)
raise 'Pleasant: Length should be greater than 3' unless length > 3
truncated_string = string.to_s
if truncated_string.length > length
truncated_string = truncated_string[0...(length - 3)]
truncated_string += '...'
end
puts truncated_string
truncated_string
end
Truncate naturally
I want to propose a solution that truncates naturally. I fell in love with the String#truncate method offered by Ruby on Rails. It was already mentioned by @Oto Brglez above. Unfortunately I couldn't rewrite it for pure ruby. So I wrote this function.
def truncate(content, max)
if content.length > max
truncated = ""
collector = ""
content = content.split(" ")
content.each do |word|
word = word + " "
collector << word
truncated << word if collector.length < max
end
truncated = truncated.strip.chomp(",").concat("...")
else
truncated = content
end
return truncated
end
Example
- Test: I am a sample phrase to show the result of this function.
- NOT: I am a sample phrase to show the result of th...
- BUT: I am a sample phrase to show the result of...
Note: I'm open for improvements because I'm convinced that there is a shorter solution possible.