Reputation: 796
I want to call a module function to define a constant in a utility module in ruby. However, when I try this I get an error message. Here comes the code and the error:
module M
ABC = fun
module_function
def self.fun
"works"
end
end
Error message:
NameError: undefined local variable or method `fun' for M:Module
Any ideas? I also tried it without self
and with M.fun
but no success...
Upvotes: 1
Views: 3601
Reputation: 107142
It is just that the method is not defined when you assign fun
to ABC
. Just change the order:
module M
def self.fun
"works"
end
ABC = fun
end
M::ABC
#=> "works"
If you dislike the order (constants below methods), you might want to consider to have the method itself to memorize its return value. A common pattern looks like:
module M
def self.fun
@cached_fun ||= begin
sleep 4 # complex calculation
Time.now # return value
end
end
end
M.fun
# returns after 4 seconds => 2017-03-03 23:48:57 +0100
M.fun
# returns immediately => 2017-03-03 23:48:57 +0100
Upvotes: 7
Reputation: 3723
Test this in you irb
console:
$ irb
2.3.3 :001 > module M
2.3.3 :002?> def self.fun
2.3.3 :003?> "worked"
2.3.3 :004?> end
2.3.3 :005?>
2.3.3 :006 > ABC = fun
2.3.3 :007?> end
=> "worked"
2.3.3 :008 > M
=> M
2.3.3 :009 > M::ABC
=> "worked"
2.3.3 :010 >
The fact is that now you defined self.fun
before using it.
In your code you used the method before defining it.
Upvotes: 2