Calling method within Class - ruby-on-rails

im new in ruby so this code is not working, please provide me the proper way of calling a method within class
Class TestClass
def testMethod
puts "hello"
end
testMethod
end
UPDATE
hi everyone thanks for all the help and comments just like #Stefan and #Matt said, my example is very uncommon to use this way and thanks for giving the right path anyway i just want to add this from my question and i found a way to work
class TestClass
def self.testMethod
puts "hello"
end
TestClass.testMethod
end

class TestClass
# a class method
def self.test_method
puts "Hello from TestClass"
end
# an instance method
def test_method
puts "Hello from an instance of TestClass"
end
end
# call the class method
TestClass.test_method
# create and instance object of TestClass
instance_of_TestClass = TestClass.new
# call the instance method of the new object
instance_of_TestClass.test_method

Your example defines a class with an instance method. You then try to call the instance method from the class - this won't work.
Instead, you need to call the method as in instance, or convert it to a class method.
class TestClass
def self.testMethod
puts "hello"
end
testMethod
end
Instance and class level distinction is a fundamental concept, you would benefit from taking some tutorials, start with a read of http://www.railstips.org/blog/archives/2009/05/11/class-and-instance-methods-in-ruby/

You have to call method in with in class like:
class TestClass
def testMethod
puts "hello"
end
def test_2
testMethod
end
end
object = TestClass.new()
puts object.test_2

Related

ruby monkey patching on the fly

Is there a way to implement monkey patching while an object is being instantiated?
When I call:
a = Foo.new
Prior to the instance being instantiated, I would like to extend the Foo class based on information which I will read from a data store. As such, each time I call Foo.new, the extension(s) that will be added to that instance of the class would change dynamically.
tl;dr: Adding methods to an instance is possible.
Answer: Adding methods to an instance is not possible. Instances in Ruby don't have methods. But each instance can have a singleton class, where one can add methods, which will then be only available on the single instance that this singleton class is made for.
class Foo
end
foo = Foo.new
def foo.bark
puts "Woof"
end
foo.bark
class << foo
def chew
puts "Crunch"
end
end
foo.chew
foo.define_singleton_method(:mark) do
puts "Widdle"
end
foo.mark
are just some of the ways to define a singleton method for an object.
module Happy
def cheer
puts "Wag"
end
end
foo.extend(Happy)
foo.cheer
This takes another approach, it will insert the module between the singleton class and the real class in the inheritance chain. This way, too, the module is available to the instance, but not on the whole class.
Sure you can!
method_name_only_known_at_runtime = 'hello'
string_only_known_at_runtime = 'Hello World!'
test = Object.new
test.define_singleton_method(method_name_only_known_at_runtime) do
puts(string_only_known_at_runtime)
end
test.hello
#> Hello World!
Prior to the instance being instantiated, I would like to extend
Given a class Foo which does something within its initialize method:
class Foo
attr_accessor :name
def initialize(name)
self.name = name
end
end
And a module FooExtension which wants to alter that behavior:
module FooExtension
def name=(value)
#name = value.reverse.upcase
end
end
You could patch it via prepend:
module FooPatcher
def initialize(*)
extend(FooExtension) if $do_extend # replace with actual logic
super
end
end
Foo.prepend(FooPatcher)
Or you could extend even before calling initialize by providing your own new class method:
class Foo
def self.new(*args)
obj = allocate
obj.extend(FooExtension) if $do_extend # replace with actual logic
obj.send(:initialize, *args)
obj
end
end
Both variants produce the same result:
$do_extend = false
Foo.new('hello')
#=> #<Foo:0x00007ff66582b640 #name="hello">
$do_extend = true
Foo.new('hello')
#=> #<Foo:0x00007ff66582b280 #name="OLLEH">

Create a method that can initialize a new object from another class

What is the correct structure to be able to call a class from another class?
I can call MyObject.new by using MyModule::MyClass::MyObject.new()
However, I would prefer to call it using:
MyModule::MyClass.myobject.new()
How do I structure my code to by able to do this?
module MyModule
class MyClass
class MyObject
def initialize(value)
#value = value
end
def method1
"This is a #{value}"
end
end
end
end
You need to define a method myobject on MyClass which returns MyObject...
module MyModule
class MyClass
class MyObject
end
def self.myobject; return MyObject; end
end
end
If I understand you correctly, you have a variable of some class and want to create a new object of the same class. Assuming that your classes all have an empty constructor, you could do a
myobject.class.new()
If you want to also have the new object the same internal state as the other one, write a method
class MyMethod
def clone
...
end
end
which performs this task.
The Answers here are right, but don't do this it's not standard and will be confusing for anyone who reads your code.
MyModule::MyClass.my_object_instance
class MyClass
def self.my_object_instance
MyObject.new
end
end
this could be better to create a factory method that returns a new instance of the class if want a shorter way to create an instance of the class.

Calling a method inside model

I am trying to trigger a method from inside the model where it is defined. But I am getting an "undefined method `completed_mission_names'" when I try to start my server. Can anybody help me find what I'm doing wrong ?
class MenteeProfile < ActiveRecord::Base
# Update trackable attributes with succeeded missions
MenteeProfile.completed_mission_names
protected
def last_completed_mission_action
end
def self.completed_mission_names
end
end
Simplified to the max, you are trying to do this:
class A
A.foo
def self.foo
puts 'Calling foo!'
end
end
This does not work because the method foo is not defined when you try to invoke it. You must define it first, then you can call it. Like so:
class B
def self.foo
puts 'Calling foo!'
end
B.foo
end
You could also call just foo instead of B.foo from within the class definition. You can add the protected keyword anywhere you like, it will not have any impact on class methods whatsoever.

How can I call methods within controller (RoR)?

I am very new to RoR and I have played around the source code. But I have a problem that I already built a 'def A' for creating first CSV file, and 'def B' for creating second CSV file. Each 'def' has its own button, but I have the third button to create all CSVs (to produce output from first and second CSV files.)
What is the possible way to do it?
def first_csv
...
end
def second_csv
..
end
def all_csv
<< how to call get first and second csv >>
end
Thanks in advance,
It should be as simple as you imagine:
def all_csv
first_csv
second_csv
end
Muntasim's answer is correct, but I have to add some additional information.
Ruby provides two types of methods..class methods and instance methods.
class MyClass < AvtiveRecord::Base
# class method
def self.foo
# do something
# within this scope the keyword "self" belongs to the class
end
# another class method which calls internally the first one
def self.bar
something = foo # self.foo could also be written
# do something with something
# within this scope the keyword "self" belongs to the class
end
# instance method
def foo
# do something
# if you use the keyword "self" within an instance method, it belongs to the instance
end
# another instance method which calls class and the first instance method
def bar
mystuff = Myclass.bar # if you want to call the class method you cannot use "self", you must directly call the class
mystuff2 = foo # self.foo is the same, because of the instance scope
return [mystuff, mystuff2]
end
end
You can call the last instance method like following
instance = MyClass.first
instance.bar

How to discover the overrided methods in Ruby/Rails?

Hey guys.
How do I know the methods that a child class overrided in my super class?
I have this:
class Test
def self.inherited(child)
# child.overrided_methods???
end
def self.foo
end
def self.bar
end
end
def Child < Test
def self.bar
puts "bar"
end
end
The method self.inherited is called when a subclass of Test is loaded. So I get the reference to this subclass in child, but I don't know how to get the methods that were overrided by this subclass.
Any ideas?
--
Arsen suggested the use of self.method_added(name) instead of self.inherited(child), but this method catches only instance methods and I want to catch class methods. Does anyone know another methods that does the same thing but with class methods?
In the last case I'll consider using a singleton and convert all this class methods to instance methods then the problem is solved.
For instance methods there is an Object::method_added(name) method you can override, similar to 'inherited' you have used:
class test
def self.method_added(name)
puts "method_added(#{name.inspect})"
super
end
end
irb(main):002:0> class Child < Test; def foo; end; end
method_added(:foo)
=> nil
You can then compare a received name to a list of your methods:
Test.instance_methods.include?(name.to_s)
With class methods this approach does not work (even if you do things like class << self magic), but a helpful fellow knew the answer: http://www.ruby-forum.com/topic/120416 :
class Test
def self.singleton_method_added(name)
puts "Class method added #{name.inspect}"
end
end
This is only the first part of the problem, because you need to know which class defined the method (it will be self) and whether the method is a new one, or overridden one. Experiment with this code:
class Test
def self.singleton_method_added(name)
if self == Test
puts "My own class method added: #{self.name}.#{name.inspect}"
elsif Test.methods(false).include?(name.to_s)
puts "Class method overriden: #{self.name}.#{name.inspect}"
elsif Test.methods(true).include?(name.to_s)
puts "My parent's class method overriden: #{self.name}.#{name.inspect}"
else
puts "New class method added: #{self.name}.#{name.inspect}"
end
end
end
Maybe a first step to the solution:
By calling child.instance_method(:bar) (if child refers to the class) or child.method(:bar) (if it refers to an instance of Child) you can get an UnboundMethod or Method object representing your method:
a = Test.instance_method(:foo)
b = Child.instance_method(:foo)
Unfortunately, a == b evaluates to false, although both refer to the same method.
def overridden_methods
klass = self.class
klass.instance_methods.select {|m| klass.instance_method(m).owner == klass}
end
Change according to your needs.

Resources