tags:

views:

46

answers:

4

In the following code example, why does the second (sheetplus) method seem to pick up the instance variables @name and @occupation fine, but the first (sheet) method return nil? I feel like I'm missing something deadly obvious, but I am basically the world's worst Ruby programmer.

class Test
def initialize(name, occupation)
  @name = name
  @occupation = occupation
def sheet
  "This is #@name, who is a/an #@occupation"
def sheetplus
  "This is #@name, who is a/an #@occupation, but why does this method succeed where the previous one fails?"
end
end
end
end
A: 

If that is the code directly pasted in, you aren't closing your initialize or sheet method definitions.

class Test
  def initialize(name, occupation)
    @name = name
    @occupation = occupation
  end
  def sheet
   "This is #@name, who is a/an #@occupation"
  end
  def sheetplus
    "This is #@name, who is a/an #@occupation, but why does this method succeed where the previous one fails?"
  end
end

Who knows what could happen at that point.

theIV
A: 

Because your keywords are in the wrong place. This will work as you expect it to:

class Test
  def initialize(name, occupation)
    @name = name
    @occupation = occupation
  end
  def sheet
    "This is #@name, who is a/an #@occupation"
  end
  def sheetplus
    "This is #@name, who is a/an #@occupation, but why does this method succeed where the previous one fails?"
  end
end
Adrian
+1  A: 

Did you really mean to nest all those definitions? Perhaps you meant:

class Test
  def initialize(name, occupation)
    @name = name
    @occupation = occupation
  end

  def sheet
    "This is #{@name}, who is a/an #{@occupation}"
  end

  def sheetplus
    "This is #{@name}, who is a/an #{@occupation}, but why does this method succeed where the previous one fails?"
  end
end
pborenstein
+1  A: 

Other people have already explained what your problem is, namely putting your ends in the wrong place, however if you are interested in knowing why you are getting the results you are getting then this is why.

t = Test.new('Joe', 'Farmer')

This creates a new instance of your Test Class. The initializer has defined a new method called sheet that does nothing but define a method called sheetplus

If you now call sheetplus then you will get an error as the sheetplus method does not exist yet (sheet has not been run to create it)

t.sheetplus
NoMethodError: undefined method `sheetplus' for 
  #<Test:0x11a9dec @name="Joe", @occupation="Farmer">
    from (irb):14

If you now call sheet it will define the sheetplus method and will return the result of defining the method (nil)

t.sheet # nil

If you now call sheetplus the method exists so it succeeds

t.sheetplus
=> "This is Joe, who is a/an Farmer, but why does this method succeed 
   where the previous one fails?"
Steve Weet
Excellent, thanks. It's good to know the *reason* behind the problem!
jbfink