For this piece of code:
class myBaseClass
def funcTest()
puts "baseClass"
end
end
myBaseClass.new.funcTest
I am getting an error:
NameError: undefined local variable or method `myBaseClass' for main:Object
from c:/Users/Yurt/Documents/ruby/polymorphismTest.rb:9
from (irb):145:in `eval'
from (irb):145
from c:/Ruby192/bin/irb:12:in `<main>'
irb(main):152:0> x=myBaseClass.new
When I tryx=myBaseClass.new, I get:
NameError: undefined local variable or method `myBaseClass' for main:Object from (irb):152
Has someone already encountered this problem? I don't think my code can be wrong.
In ruby, all constants including class names must begin with a capital letter. myBaseClass would be interpreted as an undefined local variable. MyBaseClass would work properly.
Your class name should start with a capital, working code below
class MyBaseClass
def funcTest()
puts "baseClass"
end
end
MyBaseClass.new.funcTest
Your code is wrong. Classnames must start with an uppercase in Ruby.
class MyBaseClass
fixes it.
What I don't get is how you don't get a clear error message like I do.
Code working
class MyBaseClass
def funcTest()
puts "baseClass"
end
end
MyBaseClass.new.funcTest
Related
Let's consider following code:
class Try
CONST = xxx("42")
private_class_method def self.xxx(str)
str.to_i
end
end
puts Try::CONST
It produces an error: undefined method `xxx' for Try:Class (NoMethodError)
It seems that I cannot use a class private method to initialise a constant. The example is doing nothig actually, but it is a reproduction of an error I am facing trying to read data from file into the class constant.
Is it becuse ruby tries to initialize a constant before it get know about all methodes, or am I doing something wrong?
Not really. What you can't do is to assign the value of something that still hasn't been defined to something else in order to hold its value.
It has nothing to do with the method visibility because this works:
class Try
private_class_method def self.xxx(str)
str.to_i
end
CONST = xxx("42")
end
p Try::CONST
# 42
I have searched around for the answer to this and I can see a lot of similar problems but I still do not understand what I am doing wrong here. I have declared a Ruby class and attempted to new it and then call some instance methods on the instance, so why do I get the NoMethodError on my start method?
class MyClass
def initialize
self.class.reset
end
def self.reset
...
end
def self.start(port)
...
end
end
test = MyClass.new
test.start '8082' <- here <- undefined method `start' for #<MyClass:0x2f494b0> (NoMethodError)
As you can see I am a Ruby noob. Any help would be appreciated. I can change my class structure but I would really like to understand what I am doing wrong here.
here start is a class method.
By your current approach, you can use it in the following way
MyClass.start '8080'
But if you want to use it on instance of class then use the following code
class MyClass
def initialize
self.class.reset
end
def self.reset
...
end
def start(port)
...
end
end
test = MyClass.new
test.start '8080'
You are using start as a Class variable, the method names preceded with self-keyword make those methods as Class methods. So if you really want to not change your class then you should call it like this:
MyClass.start '8080'
Else you can remove the self from your reset and start methods and make them as Instance methods and use them as:
test = MyClass.new
test.start '8082'
So why is this happening? It has to be a namespace error, I just don't understand where it is. I add a method to Fixnum like so in a file file.rb
module M
class Fixnum
def foo
return true
end
end
end
then I'll make a test like so:
require 'minitest/autorun'
require './file.rb' #the path is correct
class SomeTest < MiniTest::Test
def test_foo
assert 3.foo
end
end
which will in turn throw a
NoMethodError: undefined method `foo' for 3:Fixnum
when I run the test, and I am left scratching my head - even if I include M to include the module (applying the namespace?) for the test it still throws the error. I can use custom classes just fine, it's only when I try to add a method to an existing "open class".
Yes, you have defined your own M::Fixnum class which actually has nothing to do with ::Fixnum in the global namespace. The following will solve an issue:
module M
class ::Fixnum
def foo
return true
end
end
end
5.foo
#⇒ true
Please note, in the code above module M has no sense, since the code nevertheless monkey-patches the global Fixnum. The code is here just to show how you would monkey-patch the global class from inside another module code.
Plus, Ruby2 introduced refinements, which are likely what you are intended to use.
I am practicing to code in Ruby and when I type the following code,I get the following error.In this case,what should I do?
The code is here:
class RandomSequence
def initialize(limit,num)
#limit,#num=limit,num
end
def each
#num.times {yield(rand*#limit).floor}
end
end
i=-1
RandomSequence.new(10,4).each do |num|
i=num if i<num
end
http://ideone.com/bSkAXN
the error message I get is:
prog.rb:8:in block in each: undefined method floor for nil:NilClass (NoMethodError)
from prog.rb:8:in times
from prog.rb:8:in each
from prog.rb:14:in <main>
Add parentheses:
#num.times {yield((rand*#limit).floor)}
Without the extra parentheses, yield(rand*#limit) returns nil, and you get a NoMethodError for calling nil.floor.
What I want to achieve is something like below, i.e. calling a base class method from extended modules method:
class BaseClass
def behavior
puts 'base class behavior'
end
end
module ChildModule
def behavior
super.behavior
puts 'child module behavior'
end
end
o = BaseClass.new
o.extend ChildModule
o.behavior
and it outputs as follows (with ruby 1.9.2p290 (2011-07-09 revision 32553) [x86_64-linux])
base class behavior
t.rb:9:in `behavior': undefined method `behavior' for nil:NilClass (NoMethodError)
from t.rb:16:in `<main>'
My guess is that I can not use super, as super does not exist in the module. But it prints out that line from the super method, is that strange?
How do I achieve it what I want above?
Answer by #davidrac is working, however being more curious, would like to know, how can I get a handle to base class instance? Say for instance I added the following method to BaseClass
def behavior2
puts 'base class behavior2'
end
and overrides it in ChildModule. Now from ChildModule behavior can I make a call to behavior2 of BaseModule?
I think the correct syntax is:
module ChildModule
def behavior
super
puts 'child module behavior'
end
end