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.
Related
I am ruby beginner. I am use proc class but I am getting error.
class Timeline
attr_accessor :tweets
def each(&block) # Block into the proc
tweets.each(&block) # proc back into the block
end
end
timeline = Timeline.new(tweets)
timeline.each do |tweet|
puts tweet
end
Getting error :-
`each': undefined method `each' for nil:NilClass (NoMethodError)
How to solve this error? Please tell us!
When you define attr_accessor :tweets, you just define 2 instance methods:
def tweets
#tweets
end
def tweets=(tweets)
#tweets = tweets
end
When you call tweets inside the each method, you just call method with this name, not a local variable, so you should set #tweets in the initialize method because right now your #tweets variable is not set:
class Timeline
attr_accessor :tweets # this is just a nice syntax for instance variable setter
# and getter
def initialize(tweets)
#tweets = tweets
end
def each(&block) # Block into the proc
tweets.each(&block) # proc back into the block
end
end
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}.
The following Ruby code raises the confusing error "no id given" shown at the end. How do I avoid this problem?
class Asset; end
class Proxy < Asset
def initialize(asset)
#asset
end
def method_missing(property,*args)
property = property.to_s
property.sub!(/=$/,'') if property.end_with?('=')
if #asset.respond_to?(property)
# irrelevant code here
else
super
end
end
end
Proxy.new(42).foobar
#=> /Users/phrogz/test.rb:13:in `method_missing': no id given (ArgumentError)
#=> from /Users/phrogz/test.rb:13:in `method_missing'
#=> from /Users/phrogz/test.rb:19:in `<main>'
The core of this problem can be shown with this simple test:
def method_missing(a,*b)
a = 17
super
end
foobar #=> `method_missing': no id given (ArgumentError)
This error arises when you call super inside method_missing after changing the value of the first parameter to something other than a symbol. The fix? Don't do that. For example, the method from the original question can be rewritten as:
def method_missing(property,*args)
name = property.to_s
name.sub!(/=$/,'') if name.end_with?('=')
if #asset.respond_to?(name)
# irrelevant code here
else
super
end
end
Alternatively, be sure to explicitly pass a symbol as the first parameter to super:
def method_missing(property,*args)
property = property.to_s
# ...
if #asset.respond_to?(property)
# ...
else
super( property.to_sym, *args )
end
end
I'm trying to build a tinny DSL using the approach that Russ Olsen exposes in his book, Eloquent Ruby. However it is not working for me. Let's consider the following code:
class SayHello
def initialize
#message = "Hello."
instance_eval(yield) if yield
end
def say_it
puts #message
end
end
SayHello.new { say_it }
The error I get is:
say_hello.rb:12:in `block in <main>': undefined local variable or method `say_it' for main:Object (NameError)
from say_hello.rb:4:in `initialize'
from say_hello.rb:12:in `new'
from say_hello.rb:12:in `<main>'
But... when you use instance_eval method, the value of self shouldn't be assigned to the object that calls the method?
Thanks in advance!
When the block runs, you want self to be equal to your SayHello instance instead of the main object.
I Googled for "ruby change self for a block" and found a good answer which makes me think you should change your code to:
class SayHello
def initialize(&p)
#message = "Hello."
instance_eval(&p) if block_given?
end
def say_it
puts #message
end
end
SayHello.new { say_it }
I have this snippet:
class MyClass
def self.callWithBlock (&block)
print block.blockVar
end
end
MyClass::callWithBlock do
blockVar = 'Hello'
end
which gives me an error:
in `callWithBlock': undefined method `blockVar' for #<Proc:0x000000017ed168#./block-test.rb:9> (NoMethodError)
from ./block-test.rb:9:in `<main>'
How to access this blockVar?
If you add binding at the end of the block, that would become the result of call-ing the block, and you can eval whatever local variables assigned in that block within the context of the binding.
class MyClass
def self.callWithBlock (&block)
print block.call.eval('blockVar')
end
end
MyClass::callWithBlock do
blockVar = 'Hello'
binding
end
# => Hello