Is Method variable in a singleton class is thread safe in ruby? - ruby-on-rails

I have singleton class named TransactionCreateTemplate and this class has a instance method with one parameter def mail_payload(json_params) my question is, if we create local variable inside the mail_payload method whether that local variable is thread safe?
class TransactionCreateTemplate
include Singleton
def mail_payload(json_params)
transaction = Transaction.new(params[:name])
end
end
class Transaction
def initialize(name)
#name = name
end
end
In the above one, whether transaction local variable inside the mail_payload method is thread safe?, since it is singleton class, only one object is created and that same object is used by different threads, i am confused.

Related

Ruby variable assigned to just the keyword "new"

This is a hard one to search for, but I've got a line of Ruby in a class method where a variable is first declared by assigning it a bare new keyword and I'm not exactly sure what's going on here:
def self.html_render_controller(post)
controller = new
controller.action = 'show'
controller.post = post
controller.render_to_string
end
Coming from other languages, it looks to me like controller is implicitly being initialized as an object of some kind. And render_to_string is a Rails built-in, so my best guess is controller is initialized as some kind of Rails object?
I guess my question is really what is the value of controller after that first assignment? Or what kind of execution rules or even just documentation in Ruby would point me in the right direction for understanding this kind of shorthand?
It is not so weird as ruby code. It Is quite straight forward.
new is not a keyword is a method called on the implicit self.
You do not need parenthesis to call a method in Ruby.
If you call a method without an explicit receiver in Ruby, the receiver is going to be self, inside the body of the method self.html_render_controller, self references the class where the method is defined.
So executing new inside the method self.html_render_controller just return a new object of the class where the method is defined.
You can have more details on new from the documentation on Class, that is the class of any class in Ruby, being a class just an object of the class Class.
I'm not exactly sure what's going on here
It's the new method of your class, i.e. it returns a new instance of the class your html_render_controller method is defined in.
Since you come from other languages, it might be easier to think of controller = new() (which in fact works just fine in Ruby, but it's more idiomatic to omit empty parentheses unless needed)
what kind of execution rules or even just documentation in Ruby would point me in the right direction for understanding this kind of shorthand?
This is Ruby's default method calling mechanism when omitting a receiver: "self is the default receiver. If you don't specify any receiver self will be used."
In instance methods, self refers to the current instance. In class methods, self refers to the class the method is defined in.
These three code snippets are all equivalent: *
class MyController
def self.foo
controller = new
end
end
class MyController
def self.foo
controller = self.new
end
end
class MyController
def self.foo
controller = MyController.new
end
end
You could also replace the self after def with the class name:
class MyController
def MyController.foo
controller = MyController.new
end
end
And using the latter, most explicit form, the method could even be defined outside the class body:
class MyController
end
def MyController.foo
controller = MyController.new
end
* Note that the above examples are not identical. For example, with sub-classes, self.new would dynamically create an instance of the respective (sub-)class whereas MyController.new would always create an instance of MyController. And you usually want to define your methods within the class body to ensure proper constant lookup.
new is instantiating an object of the class where this html_render_controller method is.
You can change it to self.new instead of new, then it's clearer where this method is coming from. Since html_render_controller is a class method, self will be the class where the method is.
class Foobar
def self.foo
foobar = new
# `foobar` is a new instance of Foobar
end
end

Are ActiveJobs methods instance or class methods?

I have my job class and was wondering if I could define a helper method in such way that the variables initialized in one task are not seen by the next task that runs that job.
In other words, is the following thread safe?
class OrdersUpdateJob < ActiveJob::Base
def perform
p my_method
end
def my_method
#sth ||= 0
end
end
You have class methods and instance methods. As any class, class methods definition starts with self.
ActiveJob::Base.methods.select{|m| m == :perform}
=> []
ActiveJob::Base.instance_methods.select{|m| m == :perform}
=> [:perform]
There's no "perfom" method on the base class, but there's one perfom method on the instance methods.
I think that what you are asking is if the jobs are run by a class or an instance of that class. Seeing that only instace_methods includes :perform, I'd say that ActiveJobs are run as instances. So you should be able to use instance variables with no threading conflicts.

If self points to the klass object in ruby, why is it used as assignment in ActiveRecord?

Note: This was the best title I could think of that wouldn't make this question seem like a dup. Please feel free to edit if it does not capture the point of the question
So I've been reading Advanced Rails and I had a question that wasn't fully answered by these posts:
When to use `self.foo` instead of `foo` in Ruby methods
In Ruby. How do I refer to the class from within class << self definition?
Why use "self" to access ActiveRecord/Rails model properties?
In my understanding, within a class definition, self refers to the object referenced by the pointer klass, so for the example of an eigenclass:
class A
class << self
def to.s
"Woot"
end
end
end
is the exact same as:
class << A
def to.s
"Woot"
end
end
This is because as you open up the class, ruby is creating a Class:A (virtual) class and assigning A's klass pointer to it. To my understanding this means that within the context of this class definition self == A
My question is (assuming my understanding as I've described it above is accurate) why then in an ActiveRecord::Base subclass in Rails does the use of self seem to be merely a disambiguation of the instance and not the class itself?
For example, if I have a class: A < ActiveRecord::Base with an attribute name, I cannot call A.name = "blah" outside the class definition. However, I CAN use ( and indeed MUST use ) self in assignment within the class definition like so: self.name = "blah".
If the use of self in Ruby refers to the Class object and not the instance, why does this work in ActiveRecord and how does Rails make the distinction?
Everything is a method
Anything you do with an object is a method. When you have a class like this:
class A
attr_accessor :foo
end
obj = A.new
obj.foo = 3
obj.foo #=> 3
It might feel weird, but you didn't make any assignment here. obj.foo = 3 is only a synthatic sugar for obj.send(:foo=, 3) so in fact, it executes foo= method. obj.foo is a method as well, it simply returns a value. This is because all the instance variables are private, and there is no other way to interact with them than inside the method. attr_accessor :foo is just a shortcut for:
def foo=(value)
#foo = value
end
def foo
#foo
end
Now, when ruby see any identifier like foo, it needs to find out what it is. Firstly it assumes it is a local variable, and if not, it tries to execute it as method on current self (see below). This means that:
class A
attr_accessor :foo
def bar
foo = 'bar'
end
end
a = A.new
a.bar #=> 'bar'
a.foo #=> nil
What happened? Interpretor first uses foo as an instance variable, it is not defined. But there is an assignment next to it, so it defines a new instance variable and make an assignment. If we want to use our setter we need to tell interpreter that it is not an instance varible:
class A
attr_accessor :foo
def bar
self.foo = 'bar'
end
end
a = A.new
a.bar #=> 'bar'
a.foo #=> 'bar'
I lied. Everything is an object
about self
self in ruby is very similar to this in javascript - it means different things in different context, and it can be easily changed at any point (obviously, not recommended).
First thing you need to know is that in Ruby every class is an object, namely it is an instance of class Class. When you do
class A
it is (almost, method below uses block and has access to external scope) equivalent to:
A = Class.new
self within a context of a class is always a class itself.
class A
self #=> A
def self.bar #=> this is class method
self #=> A
end
def foo #=> this is instance method
# We are no longer in context of class, but in context of the instance, hence
self #=> instance of A
end
end
Now, for any mutable object you can defined a singleton class. This is sort of weird concept - it is an extra subclass of the original class which only has a single instance. Since all the methods come from the class, this allows you to define extra methods on a particular instance of the method without affecting other object. In most of the cases, instance class is not needed and it is created when you access it for the first time. There are couple of ways to open it:
object.singleton_class do
self #=> instance class
end
class << object
self #=> instance class
end
Any method you defined within instance class is accessible only on that particular instance, hence this:
class A
self #=> A
class << A
# we are now in the instance class of A (which is an instance of Class class)
def foo
# So this is an instance method, however our instance is a class A
self #=> A
end
end

Why does my new class method in a Rails model result in nil?

I'm just starting to learn rails. I have a test project and I added a instance method and a class method to a Post model class with some existing sample data.
class Post < ActiveRecord::Base
has_many :comments
attr_accessor :region
def sport
puts "Football"
end
def self.region
puts "West"
end
end
I correctly get "Football" when I run Post.first.sport
But I get nil when I run Post.first.region. Why doesn't rails console return "West"?
Thanks!
Since self.region is a defined as a Class method you should run Post.region to output "West"
See https://stackoverflow.com/a/11655868/1693764 for a good description of Class vs instance methods
It fails because you are using a class method on an instance object.
Do:
Post.region #=> 'west'
When you add 'self.' to a method it becomes a class method. Class method are invoked on the entire class. Instance methods on the other hand are invoked on a instance of the class.
Use class methods when you want methods that are applicable for the entire class. For example a method like find_post_with_most_comments.
Post.find_post_with_most_comments
Use instance method when you are dealing with a particular instance of the class. For example a method like first_comment
#post = Post.find(params[:post_id])
#post.first_comment
attr_accessor adds instance methods to the class.
As per your code, it creates an instance variable called "#region" during initialization of an object of Post, in the getter method.
def region
#region
end
and default value of instance variable is 'nil'. So when you access Post.first.region, it returns the default value of the instance variable.
In 'self.region' code, its defined as class method. So it can be called using the syntax 'Model.class_method'
Thus class methods are called on class objects while instance methods are called on instance objects.
Get a deeper understanding of ruby metaclasses for a complete picture, it will make you more curious about the ruby architecture, and will help you learn more.

How to function from Controller in Model ROR3.0

hi i am new ruby on rails i need to know some basic information about
how to call a function from controller to model
for ex:-
controller name : checkings
def create
#data = Checking.check()
end
model name is Checking
def check
#a="xxxxx"
end
how can i call from controller function to model function
check is instance method,you have to make class method to call by class name,def self.check end
Seems you are referring to static function call. In ruby the static functions are defined with self.
def self.check
a="xxxxx"
end
However, in rails, you should not populate instance variable in Model. In that case you can return the value from check function and assign it in controller function like
def self.check
return "xxxxx"
end
#In controller
#data = Checking.check() # "xxxxx" will be stored in #data
However, defining any function without self means its a instance function. So you need to call that function through any object of that class.
We can call the model methods from controller using two formates,
1 . Creating singleton methods.
Singleton methods are created using self keyword. example
class Check < ActiveRecord::Base
def self.check
end
end
we can call this singleton method using following format,
#checks = Check.check
2 . Creating instance methods.
Instance methods are created using without self keyword
class Check < ActiveRecord::Base
def check
end
end
we can call this singleton method using following format,
#check =Check.new
#checks = #check.check

Resources