How can I call super class method within class like:
class A
def foo
puts "lol"
end
end
class B < A
foo
end
You're trying to call an instance method from within the context of a class. This is not valid.
What would work:
class A
def self.foo
puts "lol"
end
end
class B < A
foo
end
Related
Can somebody help me distinguish When we create methods inside class << self block and when we define normal methods.
I saw somewhere code like this, but I don't know concisely the use cases of them
class Foo
def initialize
end
def bar
end
class << self
def foobar
end
end
end
The methods defined right inside a class block are instance methods:
class Foo
def bar
end
end
Methods defined within class << self inside a class block are class methods:
class Foo
class << self
def baz
end
end
end
Instance methods become available to any instance of a given class:
foo = Foo.new
foo.bar
Whereas class methods can be called directly on the class:
Foo.baz
Attempting to call instance methods on the class or vice versa results in an error:
Foo.bar #=> NoMethodError: undefined method `bar' for Foo:Class
foo.baz #=> NoMethodError: undefined method `baz' for #<Foo:0x00007ffe20055a20>
Another way to define class methods is by prefixing the method name with self.:
class Foo
def self.baz
end
end
You could also define them outside the class block, although this is rarely seen:
def Foo.baz
end
Or likewise:
class << Foo
def baz
end
end
Note that defining methods this way is not limited to classes. You can add methods to arbitrary objects, e.g.:
o = Object.new
def o.hello
"hello from o"
end
o.hello
#=> "hello from o"
Or via:
class << o
def hello
"hello from o"
end
end
Internally, these methods are added to the object's singleton class. It's a special purpose class to hold methods for just that instance:
o.singleton_class.instance_methods(false)
#=> [:hello]
For the Foo class above:
Foo.instance_methods(false) #=> [:bar]
Foo.singleton_class.instance_methods(false) #=> [:baz]
So technically, a class method is just an instance method defined on the class' singleton class.
You may need to read up on Ruby's instance and class methods.
But personally, I'd do
class Foo
class << self
def foobar
end
end
end
instead of
class Foo
def self.foobar
end
end
whenever I want to add some class level attributes, or make a method private etc as
class Foo
private
def self.foobar
end
end
wouldn't work the same as
class Foo
class << self
private
def foobar
end
end
end
Is it okay to instantiate a class A and assign it to a class variable in class B to call A's methods in B?
class A
...
end
class B
##a = A.new
def method_B
##a.method_A
end
end
You can wrap methods in a module and include them in your class(For instance methods only)
module Foo
def method_A
p 'hello'
end
end
class B
include Foo
def method_B
method_A
end
end
B.new.method_B
I want to self-initialize a class when it is inherited, but it seems inherited gets called before the inherited class is loaded. is this perhaps bad form?
class Foo
def self.inherited klass
klass.new
end
end
class Bar < Foo
def initialize
puts 'initialize'
end
end
I'm learning the object model of Ruby. I've written this script:
#/usr/bin/ruby
module MyModule
class MyBase
def class_b_method
puts "class_b_method called"
end
end
class MyClass < MyBase
attr_accessor :name
class_b_method
def set_name(name)
#name = "My name is #{name}"
end
def display_name
return #name
end
end
end
obj = MyModule::MyClass.new
obj.set_name "Martin"
puts obj.display_name
Running the code above I get this error:
module.rb:13: undefined local variable or method `class_b_method' for MyModule::MyClass:Class (NameError)
I'm trying to call the parent method within the class MyClass. What I'm doing wrong?
Inside class MyClass,self is MyClass.But you define class_b_method as an instance method inside class MyBase,i.e. method which can be called by the instances of the class MyBase,can't be invoked by the class itself. so self.class_b_method throws an legitimate error.To make your code workable write the method as below:
class MyBase
def self.class_b_method
puts "class_b_method called"
end
end
Consider this very simple logging class:
class MockLog
# ...
end
Let's add logging to all our classes:
class Module
def has_logging()
class_eval {
#log = MockLog.new
def log
self.class.instance_variable_get :#log
end
}
end
end
Now, why doesn't this work?
class Foo
has_logging
end
Foo.new.log.nil? # => false, as expected
class Bar < Foo
end
Bar.new.log.nil? # => true?! Why wasn't the `log` method inherited?
The log method was inherited (if it wasn't, you would get a NoMethodError), but your class level instance variable wasn't, so instance_variable_get returned nil. You should declare a regular class variable like:
class Module
def has_logging()
class_eval {
##log = MockLog.new
def log
##log
end
}
end
end
class Foo
has_logging
end
class Bar < Foo
end
Now it will be inherited. See Class and Instance Variables In Ruby