Forum: Ruby What is that method called?

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
941120dac2e97cf8bc1cbe0216159104?d=identicon&s=25 David Trasbo (datra)
on 2008-11-11 10:19
I need the method that has the ability to turn a long string like this:

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Pellentesque
pulvinar turpis a nisi. Cras id elit. Aliquam vitae pede nec lacus
elementum lacinia. Ut aliquam vehicula sem.

into a shorter string like this:

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Pellentesque
pulvinar turpis...

My problem is that I can't remember what the method is called. I looked
through the whole Ruby String documentation
(http://ruby-doc.org/core/classes/String.html) but I couldn't find it.
Can anyone remember what it's called?
260b864377cc125e575de59843cb02b3?d=identicon&s=25 Clifford Heath (Guest)
on 2008-11-11 11:00
(Received via mailing list)
David Trasbo wrote:
> I need the method that has the ability to turn a long string... into a shorter string...
> My problem is that I can't remember what the method is called. I looked
> through the whole Ruby String documentation...

There's no such method in Ruby. You might be thinking of the
truncate method that's part of ActionView's TextHelper module.

Clifford Heath.
F50f5d582d76f98686da34917531fe56?d=identicon&s=25 Peter Szinek (Guest)
on 2008-11-11 11:07
(Received via mailing list)
I seriously doubt this is part of standard Ruby.

You have probably seen this in ActiveSupport and/or the 'english' gem
- English::String#brief:

http://english.rubyforge.org/rdoc/classes/English/...

Cheers,
Peter
8026245386930037891a391a71e61e35?d=identicon&s=25 Mike Paul (Guest)
on 2008-11-11 11:13
(Received via mailing list)
Hi David - just done this in Agile Development

truncate(string, n) where string is the string to be shortened and n is
the
number of characters you want it shortened to.

Cheers
Mike
941120dac2e97cf8bc1cbe0216159104?d=identicon&s=25 David Trasbo (datra)
on 2008-11-11 11:49
Peter Szinek wrote:
> I seriously doubt this is part of standard Ruby.

You're right, it's not a part of the Ruby standard library:

Clifford Heath wrote:
> There's no such method in Ruby. You might be thinking of the
> truncate method that's part of ActionView's TextHelper module.

truncate is what it's called. I was actually searching for 'rails
StringHelper'... :)

Thanks for the replies!
6e366eb5a71be2bad7f383d42aeb4788?d=identicon&s=25 Justin Collins (Guest)
on 2008-11-11 12:15
(Received via mailing list)
David Trasbo wrote:
>> truncate method that's part of ActionView's TextHelper module.
>>
>
> truncate is what it's called. I was actually searching for 'rails
> StringHelper'... :)
>
> Thanks for the replies!
>

Also:

a_long_string =  "Lorem ipsum dolor sit amet, consectetuer adipiscing
elit. Pellentesque pulvinar turpis a nisi. Cras id elit. Aliquam vitae
pede nec lacus elementum lacinia. Ut aliquam ehicula sem."
limit = 86
a_long_string[0, limit] << "..."    #=> "Lorem ipsum dolor sit amet,
consectetuer adipiscing elit. Pellentesque pulvinar turpis..."


-Justin
Cec345a59245af9d06e4438a413f4eb5?d=identicon&s=25 Shot (Piotr Szotkowski) (Guest)
on 2008-11-11 13:25
(Received via mailing list)
Justin Collins:

> a_long_string =  "Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
> Pellentesque pulvinar turpis a nisi. Cras id elit. Aliquam vitae pede nec
> lacus elementum lacinia. Ut aliquam ehicula sem."
> limit = 86
> a_long_string[0, limit] << "..."    #=> "Lorem ipsum dolor sit amet,
> consectetuer adipiscing elit. Pellentesque pulvinar turpis..."

Note that in Ruby 1.8 String#[] doesn’t work on chars, but bytes,
which means the above is not reliable for multibyte strings like UTF-8:

>> polish = 'W trosce o byt i przyszłość naszej Ojczyzny'
=> "W trosce o byt i przyszłość naszej Ojczyzny"
>> polish[0, 27]
=> "W trosce o byt i przyszło\305"
>> polish[0, 30]
=> "W trosce o byt i przyszłość"

In Ruby 1.9 String#[] works on chars, so the above works as expected:

>> polish = 'W trosce o byt i przyszłość naszej Ojczyzny'
=> "W trosce o byt i przyszłość naszej Ojczyzny"
>> polish[0, 27]
=> "W trosce o byt i przyszłość"

-- Shot
Af2fc6eca30dcbbed37f0426fbc42b95?d=identicon&s=25 Boris Blaadh (boris)
on 2008-11-11 15:32
perhaps this works?




string = <<END
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Pellentesque
pulvinar turpis a nisi. Cras id elit. Aliquam vitae pede nec lacus
elementum lacinia. Ut aliquam vehicula sem.
END

lead = 90

wordlist = string.split(' ')

shorttext = ''

for word in wordlist

  break if(shorttext.length + word.length > lead)
  shorttext = shorttext + word + " "

end

# get rid of the last space
shorttext.chop!

puts "#{shorttext}..."
8666d1ebabcea440585dfe831a4af9f1?d=identicon&s=25 Brian Adkins (Guest)
on 2008-11-11 18:55
(Received via mailing list)
Justin Collins <justincollins@ucla.edu> writes:

>> Clifford Heath wrote:
>
> Also:
>
> a_long_string =  "Lorem ipsum dolor sit amet, consectetuer adipiscing
> elit. Pellentesque pulvinar turpis a nisi. Cras id elit. Aliquam vitae
> pede nec lacus elementum lacinia. Ut aliquam ehicula sem."
> limit = 86
> a_long_string[0, limit] << "..."    #=> "Lorem ipsum dolor sit amet,
> consectetuer adipiscing elit. Pellentesque pulvinar turpis..."

In general, for input strings less than the limit, you wouldn't want
"..."

class String
  # Return an ellided string no longer than total_length
  # "hello".ellide(5) -> "hello"
  # "hello there".ellide(8) -> "hello..."
  def ellide total_length
    if self.length > total_length
      raise 'total_length must be at least 3' if total_length < 3
      return self[0, total_length - 3] + '...'
    else
      return self
    end
  end
end
8666d1ebabcea440585dfe831a4af9f1?d=identicon&s=25 Brian Adkins (Guest)
on 2008-11-11 19:00
(Received via mailing list)
Boris Blaadh <nejnejnej@gmail.com> writes:

> wordlist = string.split(' ')
> # get rid of the last space
> shorttext.chop!
>
> puts "#{shorttext}..."

It is nicer to break at word boundaries in some contexts. But if it's
a single word (such as a long email address), then you'd still want to
show something more than "...". Maybe you can add a check for that.

e.g. for string = 'john.smith@hisdomain.com', lead = 15
Af2fc6eca30dcbbed37f0426fbc42b95?d=identicon&s=25 Boris Blaadh (boris)
on 2008-11-12 12:41
Brian Adkins wrote:
> Boris Blaadh <nejnejnej@gmail.com> writes:
>
>> wordlist = string.split(' ')
>> # get rid of the last space
>> shorttext.chop!
>>
>> puts "#{shorttext}..."
>
> It is nicer to break at word boundaries in some contexts. But if it's
> a single word (such as a long email address), then you'd still want to
> show something more than "...". Maybe you can add a check for that.
>
> e.g. for string = 'john.smith@hisdomain.com', lead = 15

Hehe, ok:

if shorttext.empty?
  puts wordlist[0]
else
  puts "#{shorttext}..."
end
8666d1ebabcea440585dfe831a4af9f1?d=identicon&s=25 Brian Adkins (Guest)
on 2008-11-12 21:57
(Received via mailing list)
Boris Blaadh <nejnejnej@gmail.com> writes:

>> a single word (such as a long email address), then you'd still want to
> end
That fixes the problem of showing only '...', but now 'puts
wordlist[0]' may display more than the limit.

Refining your idea a bit gave the following:

  def elide_words total_length
    return self unless self.length > total_length
    raise 'total_length must be at least 3' if total_length < 3
    words = self.split(' ')
    result = ''
    words.each do |word|
      len = total_length - (result.empty? ? 3 : 4)
      break if result.length + word.length > len
      result << ' ' unless result.empty?
      result << word
    end
    if result.empty?
      return self.elide(total_length)
    else
      return result + '...'
    end
  end

But we really don't need to find *all* the space boundaries via
split(), so the following version is about 10 times faster:

  def elide_words total_length
    return self unless self.length > total_length
    raise 'total_length must be at least 3' if total_length < 3
    len = total_length - 3 # room for '...'

    # Case 1: natural word break
    return self[0, len] + '...' if self[len,1] == ' '

    # Case 2: search backward for a char preceding a delimiter
    delim_found = false
    idx = len.downto(0) {|i|
      if delim_found
        break (i + 1) if self[i,1] != ' '
      else
        delim_found = true if self[i,1] == ' '
      end
    }

    return self[0, idx] + '...'
  end
This topic is locked and can not be replied to.