I have two classes Book::Utils, Table::Utils and I calling one class from the other which are not parent-child classes.
If I call class2 from class1 -> In class2, can we access already present class1 instance variables?
module Table
attr_accessor :account_id
class Utils
def initialize(params)
#account_id = params[:account_id]
end
def calculate
book = Book.new
final_account_id = book.get_account_id
return final_account_id
end
end
end
module Book
class Utils
def get_account_id
# Here I want to access Table's instance variables
# Like #account_id + 20
end
end
end
I am calling Table::Utils.new({account_id: 1}).calculate
Expected result : 21
Can we achieve this?
You need to pass instance of the class you need to call and then you can use accessors:
module Table
attr_accessor :account_id
class Utils
def initialize(params)
#account_id = params[:account_id]
end
def calculate
book = Book.new
final_account_id = book.get_account_id(self)
return final_account_id
end
end
end
module Book
class Utils
def get_account_id(table)
table.account_id + 20
end
end
end
or just pass the value that is needed
module Table
attr_accessor :account_id
class Utils
def initialize(params)
#account_id = params[:account_id]
end
def calculate
book = Book.new
final_account_id = book.get_account_id(account_id)
return final_account_id
end
end
end
module Book
class Utils
def get_account_id(other_id)
other_id + 20
end
end
end
Related
I have a class within a module and it has methods:
module D
class Dog
#name = 'pluto'
def setName( n )
#name = n
end
def getName ()
return #name
end
end
end
Can I access getName without creating an instance of Dog like the static method in C++? Something like:
D::Dog.getName ()
instead of:
d = D::Dog.new
d.getName()
I believe you're looking for what is known as a class method in Ruby:
module SomeModule
class SomeClass
#class_variable = "some_string" # An instance variable on a class
def self.some_class_method
#class_variable # Return can be omitted in Ruby
end
# This is how setter methods are usually written in Ruby
def self.some_class_method= new_value
#class_variable = new_value
end
end
end
SomeModule::SomeClass.some_class_method
#=> "some_string"
I have a ruby class, and in one of the methods, it calls an external function, and pass in all instance variables, and continue with the return value. Here is the code:
class MyClass
attr_accessor :name1
attr_accessor :name2
...
attr_accessor :namen
def inner_func():
all_vars = ???? # how to collect all my instance variables into a dict/Hash?
res = out_func(all_vars)
do_more_stuff(res)
end
end
The problem is the instance variables might vary in subclasses. I can't refer them as their names. So, is there a way to do this? Or Am I thinking in a wrong way?
You can use instance_variables to collect them in an Array. You will get all initialized instance variables.
class MyClass
attr_accessor :name1
attr_accessor :name2
...
attr_accessor :namen
def inner_func():
all_vars = instance_variables
res = out_func(all_vars)
do_more_stuff(res)
end
end
You could keep track of all accessors as you create them:
class Receiver
def work(arguments)
puts "Working with #{arguments.inspect}"
end
end
class MyClass
def self.attr_accessor(*arguments)
super
#__attribute_names__ ||= []
#__attribute_names__ += arguments
end
def self.attribute_names
#__attribute_names__
end
def self.inherited(base)
parent = self
base.class_eval do
#__attribute_names__ = parent.attribute_names
end
end
def attributes
self.class.attribute_names.each_with_object({}) do |attribute_name, result|
result[attribute_name] = public_send(attribute_name)
end
end
def work
Receiver.new.work(attributes)
end
attr_accessor :foo
attr_accessor :bar
end
class MySubclass < MyClass
attr_accessor :baz
end
Usage
my_class = MyClass.new
my_class.foo = 123
my_class.bar = 234
my_class.work
# Working with {:foo=>123, :bar=>234}
my_subclass = MySubclass.new
my_subclass.foo = 123
my_subclass.bar = 234
my_subclass.baz = 345
my_subclass.work
# Working with {:foo=>123, :bar=>234, :baz=>345}
Can we define utility class with instance methods and then in another class, using object of the utility class, call the instance methods?
For example,
class Usertype # utility class
def add(a, b)
c = a + b
return c
end
end
class User
user = Usertype.new
def test
return user.add(1,2)
end
end
Can this be done?
Yup, you can achieve that by using modules:
module Usertype
def self.add(a,b)
a + b
end
end
class User
def test
Usertype.add 1, 2
end
end
u = User.new
u.test
I am not sure what you are asking but here is what you can do:
class Usertype
def add(a,b)
return a + b
end
end
class User
def test
u = Usertype.new
return u.add(1,2)
end
end
Or you can use an instance variable in user:
class User
def initialize
#u = Usertype.new
end
def test
return #u.add(1,2)
end
end
I'm new to Ruby and trying to determine how I can call a class from a child object. Something like the below; however when I try it, I get an error saying "undefined local variable or method `me'"
class my_object < Object
attr_accessor :me
def initialize(attributes ={})
end
def setvalue(passed_value)
#passed_value = passed_value.to_s
end
def search(passed_value)
#passed_value.include?(passed_value)
end
end
def getMe
me_too = my_object.new
me_too.me = "test"
me_too.me.search("test")
end
end
instance.class
will give you a reference to the class
This works:
But your code had multiple errors.
class MY
attr_accessor :me
def initialize(attributes ={})
end
def setvalue(passed_value)
passed_value = passed_value.to_s
end
def search(passed_value)
passed_value.include?(passed_value)
end
def getMe
me_too = MY.new
me_too.me = "test"
me_too.search("test")
end
end
my = MY.new
my.getMe
You don't need to explicity extend Object, everything extends Object in ruby.
Your class name needs to start with a capital letter.
class MyObject
attr_accessor :me
end
me_too = MyObject.new
me_too.me = "test"
in console
me_too => #<MyObject:0x106b2e420 #me="test">
Check out some introductory ruby tutorials maybe http://ruby.learncodethehardway.org/
I have such a case:
class Person
#a class that wraps to some db table
def initialize(attributes=nil)
populate_with_attributes(attributes) if !attributes.nil?
end
def self.find(id)
#the_db.execute('query here where id....')
end
def save
#save logic and queries here
#the_db.execute('save query here')
end
# other methods .....
end
class SuperPerson
#another class that wraps to some db table
end
class SpTh < Thread
def initialize(thread_id, *other_params)
super
#thread_id = thread_id
#db = SQLite3.Database.new("./db_#{#thread_id}.sqlite3")
#....
end
def start
person = Person.find(55)
person.age = 27
person.save
end
# other methods .....
end
class Sp
def initialize
#threads_amount = 5
#threads = []
#...
raise_threads
#...
end
def raise_threads
#threads_amount.times{|thread_id|
#threads << SpTh.new(thread_id, *other_params){}
}
end
# other methods .....
end
My problem is:
How do I set the value of the #the_db variable in the Person and SuperPerson classes to the value of #db from SpTh class so that each thread has its own database?
You're accessing the class's #the_db from both the instance (in save) and the class (in self.find): wrap it in a class method, so from the instance you can access it on the class by calling self.class.connection (see the db method):
class Person
def self.connect(connection)
#the_db = connection
end
def self.connection
#the_db
end
def self.find(id)
#the_db.execute("...")
end
def db
self.class.connection
end
end
You can use singleton classes to set different connections:
db = SQLite3.Database.new("./db_#{#thread_id}.sqlite3")
person_class = Class.new(Person){ self.connect(db) }
person_class.find(1)