Not sure why this is giving me an error of
"`greet': undefined local variable or method `name' for # (NameError) from `'
class Person
def initialize(name)
#name = name
end
def greet(other_name)
"Hi #{other_name}, my name is #{name}"
return other_name
end
end
The problem is that name is a local variable only available in the constructor. To reference it as an instance variable in the greet method, use #{#name} instead of #{name}.
Related
I have a Author class and need to make some validations before initializing
class Author
include Validations
attr_accessor :name, :biography
def initialize(name, biography = nil)
validate_author
#name = name
#biography = biography
end
def to_s
"#{name}\n#{biography}"
end
end
I use module for this
module Validations
def validate_author
raise ::StandardError, 'Name is required' if name.strip.empty?
end
end
And i get this error
extentions/validations.rb:8:in `validate_author': undefined method `strip' for nil:NilClass (NoMethodError)
It's ruby application
The error gives you the clue, "for nil:NilClass (NoMethodError)", you can't apply the method .split to a Nil, what's happening that you are not passing anything so #name is nil by default, i don't know the rest of the code, but one think that you can do is use the "||" conditional writing something like.
raise ::StandardError, 'Name is required' if name.strip.empty? || name == nil
Name is not yet assigned
class Author
include Validations
attr_accessor :name, :biography
def initialize(name, biography = nil)
#name = name
#biography = biography
validate_author
end
def to_s
"#{name}\n#{biography}"
end
end
Or you can pass name to validate_author(name)
I think because the validate_author runs before setting the name instance variable. So if you move validate_author after setting instance variables, then it should work. However undefined method strip' for nil:NilClass (NoMethodError)` will still be raised as long name is nil.
I just started coding bootcamp and I am getting this error in my lab. I have tried setting the value with "" but to no avail I am still getting this error
"undefined method `breed=' for # (NoMethodError)
So after defining correctly with "end" I am still getting this error.
I currently have:
class Dog
def name=(fido)
#name= fido
end
def name
#name
end
def breed=(beagle)
#breed= beagle
end
def breed
#breed
end
end
fido = Dog.new
fido.name = fido
fido.breed = beagle
Some explanations. With
fido = Dog.new
fido.name = fido
puts "fido.name=#{fido.name} fido.name.class=#{fido.name.class}"
fido.breed = self.beagle
you are using the local variable fido just created, and sending the method beagle to self, the default receiver when there is no explicit receiver, which in this case (outside any class) is the special object main provided by the Ruby interpreter :
$ ruby -w fido_op.rb
fido.name=#<Dog:0x007ffdc2a5d620> fido.name.class=Dog
fido_op.rb:22:in `<main>': undefined method `beagle' for main:Object (NoMethodError)
The class Dog could be simplified :
class Dog
attr_reader :name
attr_accessor :breed
def initialize(name)
#name = name
end
end
fido = Dog.new('fido')
puts "fido.name=#{fido.name} fido.name.class=#{fido.name.class}"
fido.breed = 'beagle'
puts "fido.breed=#{fido.breed}"
Execution :
$ ruby -w fido.rb
fido.name=fido fido.name.class=String
fido.breed=beagle
Below is a program that implements a tree.
class Tree
attr_accessor :children, :node_name
def initialize(name_children=[])
#children = children
#node_name = name
end
def visit_all(&block)
visit &block
children.each {|c| c.visit_all &block}
end
def visit(&block)
block.call self
end
end
ruby_tree = Tree.new( "Ruby", [Tree.new("Reia"), Tree.new("MacRuby")] )
puts "Visiting a node"
ruby_tree.visit {|node| puts node.node_name}
puts
puts "visiting entire tree"
ruby_tree.visit_all {|node| puts node.node_name}
When I run this code it errors at this line
ruby_tree = Tree.new( "Ruby", [Tree.new("Reia"), Tree.new("MacRuby")] )
The error I'm receiving is
tree.rb:6:in `initialize': undefined local variable or method `name' for #<Tree:0x007f94020249f8 #children=nil> (NameError)
from tree.rb:19:in `new'
from tree.rb:19:in `<main>'
Any help would be awesome.
You have a typo in your initialize method accepts a single argument named name_children, but from the body of that method it looks like the underscore should have been a comma - name, children.
Here's the problem - line 6 #node_name = name. Where do you define that variable?
In your constructor, (initialize), why aren't you entering the variables children, and name as such instead of a children_name ? What it seems to me is that when you are trying to instantiate the class by creating the objects, when it goes to the initialize constructor, it does not find a name in there.
def initialize(name, children=[])
#children = children
#node_name = name
en
As you have define attr_accessor :name in your Model so there you have to define Children method in you model like as
def self.name
# here will be you code which you want
end
Please explain me why i should define attr_list before attr? I can not understand why i should do that?
class Question
def self.attr_list
[:id, :name]
end
attr *self.attr_list
end
class Question
attr *self.attr_list
def self.attr_list
[:id, :name]
end
end
NoMethodError: undefined method `attr_list' for Question:Class
Unlike a def, a class is executed line by line immediately after you hit return to run your program:
class Dog
x = 10
puts x
end
--output:--
10
...
class Dog
puts x
x=10
end
--output:--
1.rb:2:in `<class:Dog>': undefined local variable or method `x'
In this line:
...
class Dog
def self.greet
puts 'hello'
end
greet
end
--output:--
hello
...
class Dog
greet
def self.greet
puts 'hello'
end
end
--output:--
1.rb:2:in `<class:Dog>': undefined local variable or method `greet'
Similarly, in this line:
attr *self.attr_list
you call self.attr_list(), yet the def comes after that line, so the method doesn't exist yet.
With a def, you can write this:
def do_math()
10/0
end
and you won't get an error until you call the method.
But by the time you create an instance of a class, all the code inside the class has already executed, creating the methods and constants that are defined inside the class.
By the way, you don't ever need to use attr because ruby 1.8.7+ has attr_accessor(reader and writer), attr_reader, and attr_writer.
I was testing my code in IRB and I typed in this:
class be
def new_text
text = gets()
end
def show_text
puts "#{text}"
end
end
When I typed in new_text it worked but when I typed in show_text it came up with an error:
NameError: undefined local variable or method `text' for #<BE:0xd3cc08>
from (irb):14:in `show'
from (irb):14:in `show'
from C:/Program Files/Ruby1.9.2/bin/irb:12:in `<main>'
Any ideas of how to fix that?
Change text to be an instance variable:
class Be
def new_text
#text = gets()
end
def show_text
puts "#{#text}"
end
end
You're getting the error because the show_text method is trying to access a variable called #text which hadn't been defined in your original example.