Can't get an Array function to be visible inside ApplicationHelper

Folks,

I seem to be missing something basic here.

I am trying to call a function from my application layout that will
return me a hash of the roles for the user currently signed in. Here
is the simplified code I have in ApplicationHelper module

class Array
def to_h
Hash[*enum_with_index.to_a.flatten]
end
end

def get_cur_user_roles
[“school_admin”, “General2”].to_h
end

I call get_cur_user_roles from my layout file. When I bring up the web
page I get an error that says

undefined method `to_h’ for [“school_admin”, “General2”]:Array

However, if I capture the same code in a test.rb file (adding a
require ‘enumerator’ at the top of the file for the enum_with_index
function) and run it with “ruby test.rb” it seems to work fine.

Any thoughts on why the code above is not seeing the Array instance
method to_h in the ApplicaitonHelper? I also tried changing it to
class method by changing the declaration to self.to_h but get the same
error. Somehow the to_h method is not visible to the [“school_admin”,
“General2”] Array and I don’t understand why. I have tried restarting
the server but get the same error.

Thanks for help/pointers.

-S

On Apr 12, 3:52 am, skt [email protected] wrote:

  Hash[*enum_with_index.to_a.flatten]

undefined method `to_h’ for [“school_admin”, “General2”]:Array
the server but get the same error.

Because you write that inside the ApplicationHelper module, this is
creating a new ApplicationHelper::Array class with those 2 methods. In
you test.rb it’s not nested in a module. If you wrote your array
extensions outside of the module you shouldn’t have this problem.
(Personally I would put extensions to core classes in files in lib/
and require them from initializers rather than dumping them in
ApplicationHelper. I would also be wary of adding too many quite
specialised methods to Array.

Fred

Because you write that inside the ApplicationHelper module, this is
creating a new ApplicationHelper::Array class with those 2 methods. In
you test.rb it’s not nested in a module. If you wrote your array
extensions outside of the module you shouldn’t have this problem.
(Personally I would put extensions to core classes in files in lib/
and require them from initializers rather than dumping them in
ApplicationHelper. I would also be wary of adding too many quite
specialized methods to Array.

Fred - I agree with the points you make about having a separate file in
lib and being careful about adding too many specialized functions to
core classes like Array. However I am not very clear on why adding a
method to Array class inside ApplicationHelper module creates a new
ApplicationHelper::Array class as opposed to opening the existing core
Array class and adding the to_h method to it. As I understood it, you
could open a class anywhere and add methods to it. Sounds like there are
caveats to this that I am not very clear on - would appreciate your help
in clarifying that.

Thanks,
-S

If you wanting this to instead refer to the top level Bar class then
you can write ::Bar, or in your case ::Array.

Thanks Fred - that was very helpful.

On 12 Apr 2009, at 18:37, Sj Tib wrote:

caveats to this that I am not very clear on - would appreciate your
help
in clarifying that.

You can reopen a class from anywhere. The way modules & scoping work
in ruby means

module Foo
class Bar
end
end

defines a new Foo::Bar class (and it’s important that you can do this,
so that you can namespace your classes without trampling on other
stuff).

If you wanting this to instead refer to the top level Bar class then
you can write ::Bar, or in your case ::Array.

Fred