Simple module method call question

I'm making no progress on this, and so clearly have missed something basic.

I have a class which requires a file containing module Utils_db. There is another module 'required' in the program which instantiates this class.

I then successfully access in the class two constants - one from each module.

Utils::MENU
Utils_db::MENU

Now the trouble starts.

Right after accessing the constants, I try to call a method in one of the modules -

eval("Utils.orph_chk") <= I will be replacing the string with a construction using a variable, in the final version

This always fails. I've tried every trick I can think of, but always I get this:

../lib/setnet/SN.rb:579:in `proc_command': undefined method `orph_chk' for Utils:Module (NoMethodError)
        from ../lib/setnet/SN.rb:229:in `eval'
        from ../lib/setnet/SN.rb:579:in `proc_command'
        from ../lib/setnet/SN.rb:229:in `user_interface'
        from ../lib/setnet/SN.rb:146:in `manage'
        from ../lib/setnet/SN.rb:68:in `startup'
        from ./setnet:28

Can someone suggest why I'm not able to get to this method?

Here's the relevant Module, in abbreviated form:

module Utils

  MENU = [
  ["orph_chk", "searches nodes and links for references which cannot be resolved, and reports them"],
  ["tree_count","starting with node 'root', locates descendants of each node, displaying count at each level"],
  ["showtree","starting with node 'root', locates and displays descendants of each node"],
  ["tree_orphans","locates links which cannot be traced to the root node, and displays them"]
  ]
   def orph_chk
    puts 'orph_chk'
  end
end

Any suggestions would be much appreciated. I cannot quite figure out what to try next.

Thanks,

Tom

This always fails. I've tried every trick I can think of, but always I get
this:

../lib/setnet/SN.rb:579:in `proc_command': undefined method `orph_chk' for
Utils:Module (NoMethodError)
      from ../lib/setnet/SN.rb:229:in `eval'
      from ../lib/setnet/SN.rb:579:in `proc_command'
      from ../lib/setnet/SN.rb:229:in `user_interface'
      from ../lib/setnet/SN.rb:146:in `manage'
      from ../lib/setnet/SN.rb:68:in `startup'
      from ./setnet:28

Can someone suggest why I'm not able to get to this method?

Here's the relevant Module, in abbreviated form:

module Utils

MENU = [
["orph_chk", "searches nodes and links for references which cannot be
resolved, and reports them"],
["tree_count","starting with node 'root', locates descendants of each
node, displaying count at each level"],
["showtree","starting with node 'root', locates and displays descendants
of each node"],
["tree_orphans","locates links which cannot be traced to the root node,
and displays them"]
]

def orph_chk
  puts 'orph_chk'
end

end

You've defined an instance method, not a module method. The method as you
define it will appear in classes that use 'include Utils'. To get a module
method, define it on self:

module Utils
  MENU = [ ... ]

  def self.orph_chk
    # ...
  end
end

···

--
James Coglan

Hi,

Why are you eval'ing this? This works:

eval("include Utils; Utils.orph_chk")

I would think it has something to do with your binding when you eval.

Ben

···

On Fri, Apr 17, 2009 at 1:00 PM, Tom Cloyd <tomcloyd@comcast.net> wrote:

eval("Utils.orph_chk") <= I will be replacing the string with a
construction using a variable, in the final version

This always fails. I've tried every trick I can think of, but always I get
this:

../lib/setnet/SN.rb:579:in `proc_command': undefined method `orph_chk' for
Utils:Module (NoMethodError)
      from ../lib/setnet/SN.rb:229:in `eval'
      from ../lib/setnet/SN.rb:579:in `proc_command'
      from ../lib/setnet/SN.rb:229:in `user_interface'
      from ../lib/setnet/SN.rb:146:in `manage'
      from ../lib/setnet/SN.rb:68:in `startup'
      from ./setnet:28

Can someone suggest why I'm not able to get to this method?
Any suggestions would be much appreciated. I cannot quite figure out what
to try next.

Thanks,

Tom

James Coglan wrote:

This always fails. I've tried every trick I can think of, but always I get
this:

../lib/setnet/SN.rb:579:in `proc_command': undefined method `orph_chk' for
Utils:Module (NoMethodError)
      from ../lib/setnet/SN.rb:229:in `eval'
      from ../lib/setnet/SN.rb:579:in `proc_command'
      from ../lib/setnet/SN.rb:229:in `user_interface'
      from ../lib/setnet/SN.rb:146:in `manage'
      from ../lib/setnet/SN.rb:68:in `startup'
      from ./setnet:28

Can someone suggest why I'm not able to get to this method?

Here's the relevant Module, in abbreviated form:

module Utils

MENU = [
["orph_chk", "searches nodes and links for references which cannot be
resolved, and reports them"],
["tree_count","starting with node 'root', locates descendants of each
node, displaying count at each level"],
["showtree","starting with node 'root', locates and displays descendants
of each node"],
["tree_orphans","locates links which cannot be traced to the root node,
and displays them"]
]

def orph_chk
  puts 'orph_chk'
end

end
    
You've defined an instance method, not a module method. The method as you
define it will appear in classes that use 'include Utils'. To get a module
method, define it on self:

module Utils
  MENU = [ ... ]

  def self.orph_chk
    # ...
  end
end

--
James Coglan
http://github.com/jcoglan

Well. Live and learn. Very simple solution, but I sure wasn't looking in THAT corner of the universe.

Thank you very much.

t.

···

--

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Tom Cloyd, MS MA, LMHC - Private practice Psychotherapist
Bellingham, Washington, U.S.A: (360) 920-1226
<< tc@tomcloyd.com >> (email)
<< TomCloyd.com >> (website) << sleightmind.wordpress.com >> (mental health weblog)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Ben Lovell wrote:

eval("Utils.orph_chk") <= I will be replacing the string with a
construction using a variable, in the final version

This always fails. I've tried every trick I can think of, but always I get
this:

../lib/setnet/SN.rb:579:in `proc_command': undefined method `orph_chk' for
Utils:Module (NoMethodError)
      from ../lib/setnet/SN.rb:229:in `eval'
      from ../lib/setnet/SN.rb:579:in `proc_command'
      from ../lib/setnet/SN.rb:229:in `user_interface'
      from ../lib/setnet/SN.rb:146:in `manage'
      from ../lib/setnet/SN.rb:68:in `startup'
      from ./setnet:28

Can someone suggest why I'm not able to get to this method?
Any suggestions would be much appreciated. I cannot quite figure out what
to try next.

Thanks,

Tom

Hi,

Why are you eval'ing this?

Because the name of one of my two modules isn't known until class instantiation time. It could literally be anything. That said, I'm not at all sure my approach is the best. It's just the only one I could think of. It's also my very first use of eval, and it well may be poorly chosen.

This works:

eval("include Utils; Utils.orph_chk")
  

Hmm. I tried that, and got some kind of method error on the "include". I studied it for a good long while and simply couldn't see the problem.

I would think it has something to do with your binding when you eval.
  

Yeah, me two. I've never even thought about binding issues before, but I sure am now!

Thanks for your thoughts.

t.

···

On Fri, Apr 17, 2009 at 1:00 PM, Tom Cloyd <tomcloyd@comcast.net> wrote:

--

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Tom Cloyd, MS MA, LMHC - Private practice Psychotherapist
Bellingham, Washington, U.S.A: (360) 920-1226
<< tc@tomcloyd.com >> (email)
<< TomCloyd.com >> (website) << sleightmind.wordpress.com >> (mental health weblog)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

James Coglan wrote:

You've defined an instance method, not a module method. The method as
you define it will appear in classes that use 'include Utils'. To get a
module method, define it on self:

module Utils
  MENU = [ ... ]

  def self.orph_chk
    # ...
  end
end

Alternatively, you could use module_function() to make the instance
method a class method on the module:

module Utils
  def orph_chk
    # ...
  end

  module_function :orph_chk
end

Now you can either call the method directly (Utils.orph_chk) or mix it
in (include Utils; orph_chk). So you can have your cake and eat it too!

···

--
Posted via http://www.ruby-forum.com/\.

Suraj Kurapati wrote:

James Coglan wrote:
  

You've defined an instance method, not a module method. The method as you define it will appear in classes that use 'include Utils'. To get a module method, define it on self:

module Utils
  MENU = [ ... ]

  def self.orph_chk
    # ...
  end
end
    
Alternatively, you could use module_function() to make the instance method a class method on the module:

module Utils
  def orph_chk
    # ...
  end

  module_function :orph_chk
end

Now you can either call the method directly (Utils.orph_chk) or mix it in (include Utils; orph_chk). So you can have your cake and eat it too!
  

Hmmm. This is most interesting. Ruby amazes me every day. So much built-in cleverness. And now this, which I've never seen anywhere. I'll study up on it. Thanks very much for the heads up,

Tom

···

--

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Tom Cloyd, MS MA, LMHC - Private practice Psychotherapist
Bellingham, Washington, U.S.A: (360) 920-1226
<< tc@tomcloyd.com >> (email)
<< TomCloyd.com >> (website) << sleightmind.wordpress.com >> (mental health weblog)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~