I am learning Ruby, but no beginner in computers. If this belongs in Ruby on Rails, then please move it, but since I am using Cuba, a micro-framework, I did not put it into R-on-R. I seem to have tried quite a number of alternatives to cure this problem, with no success. This is a scaled-down sample which preserves the error. In the final system the included module will be generated by algorithm. It contains the data for drawing parts of a game, as an array of hashes. The generated code works when it is manually copied to the equivalent of "samp.erb". Now, I want to include it there automatically as sampMod.rb. The files: 1. samp.erb: the file which includes the module 2. sampMod: the file containing the module 3. terminal.txt: the console output
on 2014-06-14 07:01
on 2014-06-15 19:32
> I am learning Ruby Then you probably aren't going to understand this... 1) Get rid of 'require rubygems' unless you are using old versions of ruby and rubygems. 2) Name the file that contains the module "samp_mod.rb"--it's ruby code afterall. 3) You define a module with the 'module' keyword NOT "Module". 4) module definitions, like class definitions are terminated with the "end" keyword. 5) @ variables attach themselves to whatever object is self at the instant the @ variable is created. Similarly, when you try to retrieve the value of an @variable, ruby looks at whatever object is self at that instant and tries to lookup the @ variable in self. module A p self @x = 'hello' end p self p @x --output:-- A main nil Based on that output, @x attaches itself to A, but when @x is retrieved an object called 'main' is self, and 'main' does not have an @x instance variable, so nil is returned. 6) A def starts a new scope, and nothing outside the def can be seen inside the def. In your def here: def getsamp(index, attr) return @samp[index][attr] end @samp will be looked up in whatever object is self when the def executes, and when the def executes self will be the object that called the def. What object is that? If you add some code to the erb file, you can find out: <% require './samp_mod'; include SampMod %> self is equal to: <%= self %> ~/ruby_programs$ erb samp.erb > erb_result.txt ~/ruby_programs$ cat erb_result.txt self is equal to: main So you have the same problem as above with @x: namely, @samp is being looked up in an object called main, yet when you defined @samp it attached itself to SampMod. Note that in ruby, ALL methods are called by some object. If no object is explicitly specified to the left of the method call, then ruby uses whatever object is self to call the method. A first attempt to correct the problem might look something like this: module SampMod @samp = ['hello'] def getsamp return SampMod.samp end end But that will produce the error: `getsamp': undefined method `samp' for SampMod:Module (NoMethodError) You get that error because @ variables are private by default, so you need to provide an accessor for the variable: module SampMod @samp = ["hello"] attr_reader :samp def getsamp return SampMod.samp end end --output:-- ~/ruby_programs$ erb samp.erb > erb_result.txt ~/ruby_programs$ cat erb_result.txt self is equal to: main Result: ["hello"] Because all of the above is probably too complicated to comprehend, if you can, the easiest thing to do is just make @samp a constant: module SampMod SAMP = ["hello"] def getsamp return SAMP end end Lookups for constants work differently: the lookup starts in the inner scope (the def) and moves outwards to the surrounding scopes (the module). And you can always specify the absolute constant name: SampMod::SAMP to retrieve the constant from anywhere.
on 2014-06-17 06:54
Thank you so very much. I am hard at work understanding this, and when I do, I am sure it will be salutary to all of my future ruby efforts. I may bring bad habits of thought to ruby from a long history with assembly code, PL/I, C, C++, COBOL, FORTRAN, Perl Tcl/Tk, Objective C and Java, and while I seem to understand the surface of all that you have written (maybe some others I've forgotten), and believe it is within my grasp to work through their implications, one thing baffles me: why is it needed to remove the "require rubygems'; or ,alternatively, when is it required to add it? Even more important than the code is the manner in which you have taken the time to explain the underlying effects This Creates both extreme gratitude and admiration. It is very easy to get a smattering of Ruby from books, but without this sort of code practice, fluency will never be achieved. We need to be allowed to stumble, hurt, get up, and retry. Thanks so much again.