This project is archived and is in readonly mode.

#867 ✓resolved
Gregor Magdolen

undefined method `length' for Enumerable when calling truncate method

Reported by Gregor Magdolen | August 20th, 2008 @ 01:16 AM | in 2.x

Hello, this seems to be a small bug in text_helpers truncate method. When trying to call e.g. truncate('Hello World!', 5, '...') it generates following error:

undefined method length' for #<Enumerable::Enumerator:0x243a7a4>

Full trace:


#{RAILS_ROOT}/vendor/rails/actionpack/lib/action_view/helpers/text_helper.rb:44:in `truncate'
#{RAILS_ROOT}/app/views/admin/posts/post_list.rhtml:25:in `_run_rhtml_47app47views47admin47posts47post_list46rhtml'
#{RAILS_ROOT}/app/views/admin/posts/post_list.rhtml:22:in `each'
#{RAILS_ROOT}/app/views/admin/posts/post_list.rhtml:22:in `_run_rhtml_47app47views47admin47posts47post_list46rhtml'
#{RAILS_ROOT}/vendor/rails/actionpack/lib/action_view/base.rb:326:in `send'
#{RAILS_ROOT}/vendor/rails/actionpack/lib/action_view/base.rb:326:in `compile_and_render_template'
#{RAILS_ROOT}/vendor/rails/actionpack/lib/action_view/base.rb:301:in `render_template'
#{RAILS_ROOT}/vendor/rails/actionpack/lib/action_view/base.rb:260:in `__render_file'
#{RAILS_ROOT}/vendor/plugins/theme_support/lib/patches/actionview_ex.rb:44:in `render_file'
#{RAILS_ROOT}/vendor/plugins/theme_support/lib/patches/actionview_ex.rb:24:in `each'
#{RAILS_ROOT}/vendor/plugins/theme_support/lib/patches/actionview_ex.rb:24:in `render_file'
#{RAILS_ROOT}/vendor/rails/actionpack/lib/action_controller/base.rb:806:in `render_file'
#{RAILS_ROOT}/vendor/rails/actionpack/lib/action_controller/base.rb:741:in `render_with_no_layout'
#{RAILS_ROOT}/vendor/rails/actionpack/lib/action_controller/layout.rb:244:in `render_without_benchmark'
#{RAILS_ROOT}/vendor/rails/actionpack/lib/action_controller/benchmarking.rb:50:in `render'
/opt/local/lib/ruby/1.8/benchmark.rb:293:in `measure'
#{RAILS_ROOT}/vendor/rails/actionpack/lib/action_controller/benchmarking.rb:50:in `render'
#{RAILS_ROOT}/app/controllers/admin/posts_controller.rb:48:in `post_list'
#{RAILS_ROOT}/vendor/rails/actionpack/lib/action_controller/base.rb:1095:in `send'
#{RAILS_ROOT}/vendor/rails/actionpack/lib/action_controller/base.rb:1095:in `perform_action_without_filters'
#{RAILS_ROOT}/vendor/rails/actionpack/lib/action_controller/filters.rb:632:in `call_filter'
#{RAILS_ROOT}/vendor/rails/actionpack/lib/action_controller/filters.rb:638:in `call_filter'
#{RAILS_ROOT}/vendor/rails/actionpack/lib/action_controller/filters.rb:438:in `call'
#{RAILS_ROOT}/vendor/rails/actionpack/lib/action_controller/filters.rb:637:in `call_filter'
#{RAILS_ROOT}/vendor/rails/actionpack/lib/action_controller/filters.rb:638:in `call_filter'
#{RAILS_ROOT}/vendor/rails/actionpack/lib/action_controller/filters.rb:438:in `call'
#{RAILS_ROOT}/vendor/rails/actionpack/lib/action_controller/filters.rb:637:in `call_filter'
#{RAILS_ROOT}/vendor/rails/actionpack/lib/action_controller/filters.rb:638:in `call_filter'
#{RAILS_ROOT}/vendor/rails/actionpack/lib/action_controller/filters.rb:438:in `call'
#{RAILS_ROOT}/vendor/rails/actionpack/lib/action_controller/filters.rb:637:in `call_filter'
#{RAILS_ROOT}/vendor/rails/actionpack/lib/action_controller/filters.rb:619:in `perform_action_without_benchmark'
#{RAILS_ROOT}/vendor/rails/actionpack/lib/action_controller/benchmarking.rb:66:in `perform_action_without_rescue'
/opt/local/lib/ruby/1.8/benchmark.rb:293:in `measure'
#{RAILS_ROOT}/vendor/rails/actionpack/lib/action_controller/benchmarking.rb:66:in `perform_action_without_rescue'
#{RAILS_ROOT}/vendor/rails/actionpack/lib/action_controller/rescue.rb:83:in `perform_action'
#{RAILS_ROOT}/vendor/rails/actionpack/lib/action_controller/base.rb:430:in `send'
#{RAILS_ROOT}/vendor/rails/actionpack/lib/action_controller/base.rb:430:in `process_without_filters'
#{RAILS_ROOT}/vendor/rails/actionpack/lib/action_controller/filters.rb:624:in `process_without_session_management_support'
#{RAILS_ROOT}/vendor/rails/actionpack/lib/action_controller/session_management.rb:114:in `process'
#{RAILS_ROOT}/vendor/rails/actionpack/lib/action_controller/base.rb:330:in `process'
#{RAILS_ROOT}/vendor/rails/railties/lib/dispatcher.rb:41:in `dispatch'
/opt/local/lib/ruby/gems/1.8/gems/mongrel-1.1.5/lib/mongrel/rails.rb:76:in `process'
/opt/local/lib/ruby/gems/1.8/gems/mongrel-1.1.5/lib/mongrel/rails.rb:74:in `synchronize'
/opt/local/lib/ruby/gems/1.8/gems/mongrel-1.1.5/lib/mongrel/rails.rb:74:in `process'
/opt/local/lib/ruby/gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:159:in `process_client'
/opt/local/lib/ruby/gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:158:in `each'
/opt/local/lib/ruby/gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:158:in `process_client'
/opt/local/lib/ruby/gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:285:in `run'
/opt/local/lib/ruby/gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:285:in `initialize'
/opt/local/lib/ruby/gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:285:in `new'
/opt/local/lib/ruby/gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:285:in `run'
/opt/local/lib/ruby/gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:268:in `initialize'
/opt/local/lib/ruby/gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:268:in `new'
/opt/local/lib/ruby/gems/1.8/gems/mongrel-1.1.5/lib/mongrel.rb:268:in `run'
/opt/local/lib/ruby/gems/1.8/gems/mongrel-1.1.5/lib/mongrel/configurator.rb:282:in `run'
/opt/local/lib/ruby/gems/1.8/gems/mongrel-1.1.5/lib/mongrel/configurator.rb:281:in `each'
/opt/local/lib/ruby/gems/1.8/gems/mongrel-1.1.5/lib/mongrel/configurator.rb:281:in `run'
/opt/local/lib/ruby/gems/1.8/gems/mongrel-1.1.5/bin/mongrel_rails:128:in `run'
/opt/local/lib/ruby/gems/1.8/gems/mongrel-1.1.5/lib/mongrel/command.rb:212:in `run'
/opt/local/lib/ruby/gems/1.8/gems/mongrel-1.1.5/bin/mongrel_rails:281

It seems changing method to


def truncate(text, length = 30, truncate_string = "...")
  if text
    l = length - truncate_string.chars.to_a.length
    chars = text.chars
    (chars.to_a.length > length ? chars.to_a[0...l].to_s + truncate_string : text).to_s
  end
end

will solve the problem.

My configuration is following: OS: Mac OS X 10.5, Rails: rails 2.1.0, Ruby: ruby 1.8.7, Application server: mongrel 1.1.5

Comments and changes to this ticket

  • Peter Wagenet

    Peter Wagenet August 23rd, 2008 @ 07:20 PM

    If your fix works, make a patch with some tests to verify it. If you don't know where to start, check out: http://rails.lighthouseapp.com/p...

  • Ronald de Gunst

    Ronald de Gunst August 23rd, 2008 @ 10:44 PM

    truncate takes an option hash instead of separate length and omission arguments See http://www.rubyonrails.org/depre... for details.

  • Gregor Magdolen

    Gregor Magdolen August 23rd, 2008 @ 11:11 PM

    @peter: thanks, im new to ruby and rails and i found bug by "accident", but i'll try my best to make a patch.

    @ronald: can you be more specific? I can't find enough information on site you provided. I also believe I have installed latest stable release of rails (installed via gem)

  • Peter Wagenet

    Peter Wagenet August 24th, 2008 @ 01:53 AM

    Gregor, it seems we often run into these sorts of things by accident :) Good luck with the patch. I can take a look at it for you once you get it up. Let me know if you have any difficulties.

  • Boo Yah

    Boo Yah September 28th, 2008 @ 06:08 AM

    Peter, I ran into the same issue but solved the problem by eliminating the calls to the 'chars' function:

    
    def truncate(text, length = 30, truncate_string = "...")
      if text.nil? then return end
      l = length - truncate_string.length
      (text.length > length ? text[0...l] + truncate_string : text).to_s
    end
    
  • Peter Wagenet

    Peter Wagenet September 28th, 2008 @ 04:32 PM

    @Boo Yah: You'll want to make sure that's the right solution. The chars method is for dealing with Unicode, so removing that call may make the truncate method no longer Unicode safe.

  • tigris

    tigris September 30th, 2008 @ 07:25 AM

    Gregor,

    The issue is that 1.8.7 ruby introduced it's own chars() method onto the String object, overwriting ActiveSupport's attempts to patch it's own chars() method on there.

    I believe if you roll back to ruby 1.8.6, your problem will go away.

    I am unsure if it is fixed in newer versions of rails, I am about to go and update my rails now and make sure it all works on 1.8.6 before I attempt to upgrade ruby again.

    regards, Danial

  • tigris

    tigris September 30th, 2008 @ 07:35 AM

    Edit: looks fixed in current rails

    http://github.com/rails/rails/co...

    09/21/08: Change all calls to String#chars to String#mb_chars.

  • iGEL

    iGEL November 15th, 2008 @ 11:21 PM

    • Tag changed from actionpack, bug, enumerable, helper to actionpack, activesupport, bug, enumerable, helper, multibyte

    I can verify this problem. "Hello".chars is returning an Enumerable::Enumerator on Rails 2.2 RC1 and 2 with ruby 1.8.7. With Rails 2.1.2/Ruby 1.8.7 it worked fine.

    Using Ubuntu 8.10 here.

    "Hello".chars.downcase NoMethodError: undefined method downcase' for #<Enumerable::Enumerator:0xb6809e84>

  • iGEL

    iGEL November 16th, 2008 @ 12:12 AM

    After 2 hours of searching for a bug in Rails, I've realized, that I've should have read tigris completely. Sorry...

  • DHH

    DHH November 16th, 2008 @ 08:42 PM

    • Assigned user set to “Michael Koziarski”
  • Michael Koziarski

    Michael Koziarski November 17th, 2008 @ 01:29 PM

    • State changed from “new” to “resolved”

    2.1.x doesn't support ruby 1.8.7.

    Either downgrade to 1.8.6 or upgrade rails to 2.2 RC2

  • Nathan de Vries

    Nathan de Vries November 25th, 2008 @ 07:11 AM

    Can this not be solved (albeit hackishly) by dropping the following into an initializer?

    
    class String
      def chars
        ActiveSupport::Multibyte::Chars.new(self)
      end
      alias_method :mb_chars, :chars
    end
    

    I'm using that trick to get Mephisto + Rails v2.0.5 running under 1.8.7.

  • Micah Wedemeyer

    Micah Wedemeyer November 2nd, 2009 @ 10:16 AM

    Nathan, I could kiss you. Your little snippet was enough to get me up and running while I search for a way to migrate a legacy app to something new.

Create your profile

Help contribute to this project by taking a few moments to create your personal profile. Create your profile »

<h2 style="font-size: 14px">Tickets have moved to Github</h2>

The new ticket tracker is available at <a href="https://github.com/rails/rails/issues">https://github.com/rails/rails/issues</a>

Pages