On Feb 1, 2007, at 11:10 PM, Chris Shea wrote:
> I have a vacuum fluorescent display in my office, and I've been
> messing around with it. Now that I've figured out how to communicate
> with the serial connection it's time for some fun. Its shortcoming is
> its 2 lines of 20 chars. So I naturally wrote a fortune cookie program
> for it.
>
> I want to make adding new fortunes easy (and without having to figure
> out myself where to force a line break), so I basically need to split
> a string (approximately) in half at a word boundary. This is what I
> have:
>
> class String
>   def halve
>     first_half = ''
>     second_half = self
>     until first_half.length >= length / 2
>       match = / /.match(second_half)
>       first_half << match.pre_match << ' '
>       second_half = match.post_match
>     end
>     [first_half.strip, second_half]
>   end
> end
>
> I have a feeling there's a one-line regexp that can do this. Am I
> right? If not, is there a better way?

Good solutions already, but I had to chime in with one less clever  
and without regexps.
I also didn't like "halve" as a name so I used "cleave".

Enjoy!


class String
   def cleave
     middle = self.length/2
     early = self.rindex(' ', middle)
     late = self.index(' ', middle)

     if self[middle,1] == ' '
       [ self[0...middle], self[middle+1..-1] ]
     elsif early.nil? && late.nil?
       [ self.dup, '' ]
     elsif early.nil?
       [ self[0...late], self[late+1..-1] ]
     elsif late.nil?
       [ self[0...early], self[early+1..-1] ]
     else
       middle = middle - early < late - middle ? early : late
       [ self[0...middle], self[middle+1..-1] ]
     end
   end
end

if __FILE__ == $0
   require 'test/unit'
   class StringCleaveTest < Test::Unit::TestCase
     def test_nospaces
       assert_equal [ 'whole',
                      '' ], 'whole'.cleave
       assert_equal [ 'Supercalifragilisticexpialidocious',
                      '' ], 'Supercalifragilisticexpialidocious'.cleave
     end
     def test_exact_middle
       assert_equal [ 'fancy',
                      'split' ], 'fancy split'.cleave
       assert_equal [ 'All good Rubyists',
                      'know how to party' ], 'All good Rubyists know  
how to party'.cleave
     end
     def test_closer_to_start
       assert_equal [ 'short',
                      'splitter' ], 'short splitter'.cleave
       assert_equal [ 'Four score and',
                      'seven years ago...' ], 'Four score and seven  
years ago...'.cleave
       assert_equal [ 'abc def',
                      'ghijklm nop' ] , 'abc def ghijklm nop'.cleave
     end
     def test_closer_to_end
       assert_equal [ 'extended',
                      'split' ], 'extended split'.cleave
       assert_equal [ 'abc defghi',
                      'jklm nop' ] , 'abc defghi jklm nop'.cleave
     end
   end
end


Rob Biedenharn		http://agileconsultingllc.com
Rob / AgileConsultingLLC.com