hi i m new to ruby on rails please let me know is it possible to declare a variable within the function/method
def fun1
#initialized a global variable
end
def fun2
#access value
end
is it possible get value of a variable declared in fun1 function by fun2 function
To create a truly global variable, use $:
def fun1
$foo = 'bar'
end
def fun2
puts $foo
end
Here $foo is available outside the class instance once fun1 has been called.
As noted in the first comment, this should be used sparingly:
They are dangerous because
they can be written to from anywhere. Overuse of globals can make
isolating bugs difficult; it also tends to indicate that the design of
a program has not been carefully thought out.
What you're probably asking for is an instance variable, which uses #:
def fun1
#foo = 'bar'
end
def fun2
puts #foo
end
Here #foo is available anywhere in the current instance of the class, again once it has been declared by calling fun1.
See for example this on the various variable scopes in ruby.
First of all, it would be better if you could share your actual scenario for what you need to define a global variable from a function. There might be a better, manageable, DRY approach for your solution.
Secondly, apart from the answer from "Thilo", here are few references showing the usage of global variables for rails in different situations. Not just for ruby. You need it for rails right?
https://stackoverflow.com/a/4110947/1160106
https://stackoverflow.com/a/3600860/1160106
Related
I am new to Ruby and to Rails, and am trying to understand fully what I'm reading.
I am looking at some of the Rails source code, in this case action_controller/metal/instrumentation.rb.
def render(*args)
render_output = nil
self.view_runtime = cleanup_view_runtime do
Benchmark.ms { render_output = super }
end
render_output
end
I understand that *args is using the splat operator to collect the arguments together into an array. But after that, it stops making much sense to me.
I can't fathom why render_output is set to nil before being reassigned to equal super and then called with no arguments. I gather that some speedtest is being done, but coming from other languages I'd expect this to just be something more like Benchmark.ms(render_output) or perhaps Benchmark.start followed by render_output followed by Benchmark.end. I'm having a hard time following the way it works here.
But more importantly, I don't really follow why args isn't used again. Why bother defining a param that isn't used? And I mean, clearly it is getting used-- I just don't see how. There's some hidden mechanism here that I haven't learned about yet.
In this context, it is important to note how super works, because in some cases it passes implicitly arguments and you might not expect that.
When you have method like
def method(argument)
super
end
then super is calling the overridden implementation of method implicitly with the exact same arguments as the current method was called. That means in this example super will actually call super(argument).
Of course, you can still define a method call that explicitly sends other arguments to the original implementation, like in this example:
def method(argument)
super(argument + 1)
end
Another important edge-case is when you want to explicitly call super without any arguments although the current method was called with arguments then you need to be very explicit like this
def method(argument)
super() # note the empty parentheses
end
Let me try to describe you what I think this code does.
*args*
is using the splat operator to collect the arguments together into an array
that is totally correct, however they don't use it, and if you will go to master branch, they just changed it to *. Asking why it is defined and not used, I think that's question about bad design. They should have called it _args or at least like it is now just single splat *.
render_output is set to nil because of scopes, it has to be explicitly defined out block, lambda, proc in order to store value in it, otherwise its visibility will be locked only to those lambda, proc, block execution. Refer to this article
Benchmark.start. Blocks are great ruby construction. You are totally correct that speedtest is done, we can see it is just decorator for benchmark library.
source.
You are wondering why we cannot just pass it as Benchmark.ms(render_output), that's because what will be given to benchmark ms function? It will be given result, like <div> my html </div. And how we can measure this string result - no how. That's why we calling super right in this block, we want to access parent class function and wrap it inside block, so we are not calling it, we just construct it, and it will be called inside benchmark lib, and measured execution like
class Benchmark
...
def realtime # :yield:
r0 = Process.clock_gettime(Process::CLOCK_MONOTONIC)
yield
Process.clock_gettime(Process::CLOCK_MONOTONIC) - r0
end
...
end
So here we can count realtime of function execution, this is the code from original library
I accidentally came across this piece of code in Ruby's Postgresql gem:
### Convenience alias for PG::Connection.new.
def self::connect( *args )
return PG::Connection.new( *args )
end
I played around a bit and turns out that this thing is used just like a normal module class method (it's called like this: PG.connect). In fact we could instead say def self.connect ( #args ) ... end and it would work just the same.
Since self::whatever is a first for me I'm wondering what exactly does self namespaces in such a context and what is its true purpose in this case. Can anyone help shed some light on this?
:: is the scope resolution operator. So self::connect resolves connect from self. Which means that its equivalent to self.connect. You can see how it works from this very contrived example:
class Foo; end
class Bar
def Foo::baz
"Hello World"
end
end
puts Foo.baz # "Hello World"
Of course we could also just use def Foo.baz to get the exact same result.
Using double colons for method definition is discouraged by the Ruby Style guide:
Do not use :: to define class methods.
# bad
class Foo
def self::some_method
end
end
# good
class Foo
def self.some_method
end
end
Its also not recommended for anything other than referencing constants and constructors:
Use :: only to reference constants (this includes classes and modules)
and constructors (like Array() or Nokogiri::HTML()). Do not use :: for
regular method invocation.
:: is, in some situations, somewhat equivalent to .. (I will leave out a precise definition in which exact situations it is equivalent and to what degree, because I freely admit I don't fully know it myself, nor is it well-documented.)
Here is an example of where :: and . behave differently:
module Foo
def self.Bar
'method'
end
Bar = 'constant'
def self.Qux; end
end
Foo.Bar
#=> 'method'
Foo::Bar
#=> 'constant'
Foo::Bar()
#=> 'method'
Foo.Qux
Foo::Qux
# NameError (uninitialized constant Foo::Qux)
Foo::Qux()
[Note: this is not a perfect example, since this is about the message sending side of things whereas your example is about the method definition side of things. I believe on the method definition side, they are 100% identical since def never defines a constant and thus there is no ambiguity.]
All Style Guides heavily advocate against this usage, from strongly advising against the message sensing part of it to flat out forbidding both usages of it. The main reason for this is the fact that the two behave differently for message sends, and this may lead to confusion. It is also simpler to explain the conceptual difference between method lookup (dynamic, upwards in the inheritance chain) and constant lookup (first static, lexically outward, then dynamic, upwards in the inheritance chain) when not using the same operator for both.
The typical style used by many Rubyists is:
NEVER use :: for singleton method definition, always use ..
ALWAYS use :: for referencing singleton methods in documentation, never use ..
ALWAYS use . for usage examples of message sends (including singleton methods) in documentation, never use ::.
NEVER use :: for message sends (including singleton methods), always use ..
Those last two are sometimes softened to allow for methods that are supposed to return modules or classes, and to allow for methods that act as factories (e.g. Nokogiri::XML) to be invoked via message sends that "look like" constant lookup, (e.g. Nokogiri::XML('<root/>') instead of Nokogiri.XML('<root/>')).
There was a feature request for removing this usage of ::, but it was rejected mostly because of backwards-compatibility concerns.
In a common application we use instance variables so that we can access them in our views. But in a Rails api application what would the need be?
Is there any performance difference between using a local or instance variable In this context of Controllers?
I do not understand why rails uses instance variables in the create and index method in an api application generated by scaffold if the variable is not reused
def show
user = User.find(params[:id])
render json: UserSerializer.new(user)
end
def show
#user = User.find(params[:id])
render json: UserSerializer.new(#user)
end
In this exact example, there is no functional difference.
Is there any performance difference? Or is there material performance difference? I do not know the answer to the first question. The answer to the second question, I imagine, is 'no' unless you are doing this at some unimaginably large scale. Even then, it's hard to imagine.
BTW, you could just do:
def show
render json: UserSerializer.new(User.find(params[:id]))
end
In your example, there is no need for a variable, either user or #user.
There is a very clear practical difference in how lexical and instance variables work:
class Thing
def initialize
#ivar = "Hello World"
end
def foo
#ivar
end
end
> Thing.new.foo
=> "Hello World"
Since instance variables are attached to the instance they can be shared among methods of an object without passing by value as typically used by callbacks:
class API::V1::ThingsController < ::ApiController
before_action :set_thing, except: [:create, :index]
def show
respond_with #thing
end
# ...
private
def set_thing
#thing = Thing.find(params[:id])
end
end
This can be immensely useful when considering the convention over configuration focus of rails. Controller IVARs are also available in the view through the view context.
Lexical variables on the other hand only exist in the lexical scope where the are defined (the method, block, proc or lambda):
class Thing
def initialize
lex = "Hello World"
end
def foo
lex
end
end
> Thing.new.foo
NameError: undefined local variable or method `lex' for #<Thing:0x007f87068b5968>
They are preferable when you need a short lived variable with a local scope. Rails also has locals which is actually a hash where you can stuff things when rendering which should not be conflated with the Ruby concept of lexical variables. Rails uses method_missing in the view context to proxy to the locals hash.
The performance difference is most likely extremely negible as both are just variables that are bound to a scope - either the object or a method/block. The lexical variable will recycled by the GC when the scope is closed (the method finishes) though while an instance variable will persist with the object. This is rarely an issue though.
The performance difference will be negligible.
But there's two competing guidelines at work. One is "Always use the weakest construction." Don't use double "quotes" if you can use single 'quotes'. Don't use a regular expression if you can use String#index. Don't use an instance variable if you can use a local variable.
The other guideline is "Design for testing." If you use an instance variable, your test can inspect it with assigns(:user). That rule trumps the "weakest construction" rule. So use an instance variable, and write lots of automated tests!
there is no difference talking about functionality in that example. but creating an instance variable is to let that variable be accesible later, maybe on the view or in another method, in this case, talking about api's (you don't have views), if you do not plan to use #user in another method inside that controller for example, you don't need to create it, with just a local variable, it's enough.
talking about performance, I don't think there will be much differences, at least something noticeable.
And as a comment:
"An instance variable continues to exist for the life of the object that holds it. A local variable exists only within a single method, block or module body."
I am having some trouble understanding the syntax of variables and symbols in Ruby. I am reading a book called Agile Web Development with Rails 4. I am trying to learn both Ruby and Rails so that I can build websites.
The books and tutorials I have been reading sometimes have variables with the "#" symbol in front of them, and then some variables do not have the # symbol in front of them. What is the difference between them?
Also, I am getting confused with the colon. Sometimes I see variables where the colon is in the front, such as :order, and then I see variables where the colon is at the end, such as colon:. I do not understand what the colon is doing.
Please help me understand the Ruby syntax.
Variables starting with # are instance variables, "properties" in other languages. Whereas 'classic' variables are local to the scope of their method/block, instance variables are local to a specific instance of an object, for example:
class Foo
def initialize(bar)
#bar = bar
end
def bar
#bar # the variable is specific to this instance
end
def buzz
buzz = 'buzz' # this variable is not accessible outside of this method
end
end
You may also see variables starting with ##, which are class variables, and are accessible by every instance of the class and shared with every instance of the subclass. Usage of those variables is usually discouraged, primarily because subclasses share the variable, which can cause a lot of mess.
In Ruby everything is an object, classes are objects (instances of class Class), so you can also have class instance variables:
class Foo
def self.bar
#bar #we are in class Foo's scope, which is an instance of class Class
end
def self.bar=(bar)
#bar = bar
end
def bar
#bar # Foo.new.bar != Foo.bar
end
end
What you call "variables with a colon" are not variables. They are a particular type of string, called a symbol, that is immutable and optimized for quick identification by the interpreter, in fact, those are stored internally as pointers, so that :this == :this is a very quick operation.
This property makes them good candidates for hash keys because they offer quick retrieval or for "flags" to pass to a method; Think of them as a sort of loose constant that "stands for" what they say. Their immutability is also dangerous: All symbols ever created never get garbage collected; It's easy to create a memory-leak by creating thousands of symbols, so use them wisely.
UPDATE since ruby 2.2 symbols may be garbage-collected in certain cases (when no reference is kept and no comparison is needed)
Variables with an # symbol are instance variables. What this means is that they persist as long as the instance of the class they are declared in persists. So if you have a class called Message and each message has a variable called #subject, when you instantiate a new message it will keep that subject variable in memory as long as the message object itself lives. Now if it did not have the # symbol, once the function it was declared in "went out of scope" aka finished, the variable would be "lost" as the function was complete and the memory was reclaimed by the Ruby VM. There are also "class variables" that are prefaced with two # symbols. This means the variable is shared across all instances of a class.
As for the colon, if it is before a variable that means it is a "symbol", which is usually used as an identifer for hashes and other bits of data in Ruby. If it is at the end of a word that means it is the key portion of a hash identifier in Ruby 1.9+ syntax.
Instance Variables: (#foo = '123') An instance variable is defined and keeps its value throughout the current instance of the request. In the rails mvc paradigm, the most common use of instance variables are used to help communicate data from the controller to the view, and allows you ro define things in one part of the controller and use in another.
class ProjectsController < ApplicationController
before_filter :find_project
def show; end
def update
if #project.update_attributes(params[:project])
...
end
end
private
def find_project
#project = Project.find(params[:id])
end
end
In the above code, you can see that there is a before filter that gets ran before every method. In the above case, we find the current project and save it to an instance variable. And because its an instance method, its able to be access anywhere within this class as well as the views used to render the html.
Local Variables: (foo = '123') Pretty much exactly what the name implies, they are only able to be accessed within the current method (def) of where they are defined.
sometimes have variables with the "#" symbol in front of them, and then some variables do not have the # symbol in front of them.
Variables with the "#" symbol are instance variables,which are not preceded by #,can be constants or local variables or global variables. Read Ruby Programming/Syntax/Variables and Constants.
Sometimes I see variables where the colon is in the front, such as :order
They are called symbols.
and then I see variables where the colon is at the end, such as colon:. I do not understand what the colon is doing.
These probably the Hash syntax(as you give us hints,so I would guess),where keys are symbols. Example : {foo: 1} - this is a Hash.
Also read as you requested :
Normal Variables Vs Instance variable in Ruby, Whats the difference?
module Foo
attr_accessor :val
end
module Bar
def bar
val = 50
end
end
class FooBar
include Foo
include Bar
end
fb = FooBar.new
puts fb.bar # 50
puts fb.val # nil
I would like to, from within Bar, change Foo's "val" value.
Just so you know, I'm trying to do this because I want to add user authentication through a Facebook Canvas app in Clearance (0.8.2 (old, I know)). The variable that I want to change is https://github.com/thoughtbot/clearance/blob/b8ccca00d91cb336e044b76b5c6ae1d8de9d2d8d/lib/clearance/authentication.rb#L25.
This module gets included into ApplicationController, and I'm including another module afterwards (FacebookAuthenticationHelper) that does something like
def authenticate_facebook
current_user ||= facebook_user if coming_from_facebook?
end
I would love to know if there's a better way to do this as well. I'm not using OAuth, I'm just saving Facebook's user_id sends to my app from signed_request into my DB.
Thanks!
In ruby, any statement of the form varname = value will create a local variable named varname if it doesn't already exist. This is even true within class methods where the class has a setter method of the same name. Furthermore, if a local variable exists, it takes precedence over getters and setters. For example:
class Demo
attr_accessor :foo
def demonstrate!
#foo = 1 #1: Set member variable foo, so we get meaningful output
puts foo #2: Prints 1 (this calls the getter)
puts self.foo #3: Prints 1 (also calls the getter)
foo = 2 #4: Creates a LOCAL variable named foo with the value 2
puts foo #5: Prints 2 (locals take precedence over getters)
puts self.foo #6: Prints 1 (calls the getter - the member variable hasn't changed)
self.foo = 3 #7: Use SELF to ensure you call a getter or setter
puts foo #8: Prints 2 (the local again)
puts self.foo #9: Prints 3 (the member, which is now 3)
end
end
The bad thing about this system is: Look at lines 2 and 5. The same exact code does different things! On line 2, the local variable foo didn't exist yet, so ruby did the "next best" thing and called the getter. But on line 5, the local foo exists, so it takes precedence.
I'd say that this is bad language design: If setters can't be called without self, why should it be okay for getters - especially when it can lead to rickety, context-sensitive code like the above? But it's what we have to work with, and it leads to some general guidelines:
If you can, use #foo. It's obvious what that does.
If you're using a getter or setter, always use self, even when it's not strictly necessary. This makes it obvious what you're calling. It also guarantees your code won't behave differently if you add a local with the same name later.
If you do 1 and 2, you can assume that anything without a # or a self is a local variable (or a function call, but you can probably tell those apart by name).
And that ended up being a bit long-winded, but I was unable to find a good demonstration of the getter/setter/local problem to link to. So maybe this is it - hope it's helpful!