Ruby: How to call function before it is defined?
In Ruby, function definitions are statements that are executed exactly like other statement such as assignment, etc. That means that until the interpreter has hit your "def check_data" statement, check_data doesn't exist. So the functions have to be defined before they're used.
One way is to put the functions in a separate file "data_functions.rb" and require it at the top:
require 'data_functions'
If you really want them in the same file, you can take all your main logic and wrap it in its own function, then call it at the end:
def main
groups = ...
check_data
save_data_in_database
end
def check_data
...
end
def save_data_in_database
...
end
main # run main code
But note that Ruby is object oriented and at some point you'll probably end up wrapping your logic into objects rather than just writing lonely functions.
Method call before method in Ruby?
TL;DR
This code doesn't do what you think it does. Don't do stuff like this.
Ruby's Top-Level Object
Ruby lets you define methods outside a class. These methods exist on a top-level object, which you can (generally) treat as a sort of catch-all namespace. You can see various posts like What is the Ruby Top-Level? for more details, but you shouldn't really need to care.
In your original post, method_one is just a method defined in the top-level. It is therefore available to classes and methods nested within the top-level, such as MyClass.
Methods in Classes
Despite what you think, the following doesn't actually declare a :method_one class or instance method on MyClass:
class MyClass
method_one
def method_two; end
end
Instead, Ruby calls the top-level ::method_one
during the definition of the class, but it never becomes a class method (e.g. MyClass::method_one
) or an instance method (e.g. MyClass.new.method_one
). There might be a few use cases for doing this (e.g. printing debugging information, test injection, etc.) but it's confusing, error-prone, and generally to be avoided unless you have a really strong use case for it.
Better Options
In general, when you see something like this outside an academic lesson, the programmer probably meant to do one of the following:
- Extend a class.
- Add a singleton method to a class.
- Include a module in a class.
- Set up a closure during class definition.
The last gets into murky areas of metaprogramming, at which point you should probably be looking at updating your class initializer, or passing Proc or lambda objects around instead. Ruby lets you do all sorts of weird and wonderful things, but that doesn't mean you should.
How to call function in ruby
In Ruby, you must first define a method. You do that using the syntax
def method_name
# code goes here
end
To call the method, you simply type in the method name
method_name
In your case, you had the first step down
def install_apache
end
You need to add another line in your code like so
install_apache
Is it possible to call a previously defined method from within a method of the same name?
You can make use of alias_method
to access the previous definition here:
class User
def avatar=(attachable)
# do activestorage stuff
end
alias_method :original_avatar=, :avatar=
def avatar=(attachable)
# do my stuff
self.original_avatar=(attachable)
end
end
Call method only if it exists
If you are not satisfied with the standard ruby syntax for that, you are free to:
class Object
def try_outside_rails(meth, *args, &cb)
self.send(meth.to_sym, *args, &cb) if self.respond_to?(meth.to_sym)
end
end
Now:
resource.try_outside_rails(:phone_number)
will behave as you wanted.
call before methods in model on ruby
You can do this with prepend
. prepend
is like include
in that it adds a module to the ancestors of the class, however instead of adding it after the class it adds it before.
This means that if a method exists both in the prepended module and the class then the module implementation is called first (and it can optionally call super
if it wants to call the base class).
This allows you to write a hooks module like so:
module Hooks
def before(*method_names)
to_prepend = Module.new do
method_names.each do |name|
define_method(name) do |*args, &block|
puts "before #{name}"
super(*args,&block)
end
end
end
prepend to_prepend
end
end
class Example
extend Hooks
before :foo, :bar
def foo
puts "in foo"
end
def bar
puts "in bar"
end
end
In real use you would probably want to stash that module somewhere so that each call to before
doesn't create a new module but that is just an inplementation detail
Execute method like before_filter in Rails
You don't need a gem for simple metaprogramming like this. What you can do is redefine the "after" method to call the "before" method and then the original "after" method.
This works even when using before
multiple times on the same method or when creating a chain of before
calls.
module MySuperModule
def before meth, opts
old_method = instance_method(meth)
define_method(meth) do
send opts[:call]
old_method.bind(self).call
end
end
end
class MyClass
extend MySuperModule
def foo
puts "foo"
end
def bar
puts "bar"
end
def baz
puts "baz"
end
before :foo, call: :bar
before :bar, call: :baz
end
MyClass.new.foo
# baz
# bar
# foo
Rails call back before every calling a method before every static method
Try this
class A
def self.hello
print "how are"
end
def self.before_stuff
print "you"
end
begin
print "hello,"
end
end
A.hello
Related Topics
Is It Acceptable Having Parameter in Class Constructor
Argumenterror (Wrong Number of Arguments (Given 2, Expected 1)) After Updating to Ruby 3.0
Ruby: How Does Constant-Lookup Work in Instance_Eval/Class_Eval
Ruby: Why Does '#Hash' Need to Overridden Whenever '#Eql' Is Overridden
What Does It Mean to Yield Within a Block
Error Installing "Kgio-2.9.2" Gem on Windows
How to Figure Out Which Step I'Ve Just Executed in Cucumber's Afterstep Hook
Ruby - How to Thread Across Cores/Processors
What Do Ruby's Printf Arguments Mean
Why Won't Ruby Allow Me to Specify Self as a Receiver Inside a Private Method
Sort an Array in Ruby Ignoring Articles ("The", "A", "An")
Using Ruby, What Is the Most Efficient Way to Get the Content Type of a Given Url
How to Execute 2 or More Commands in the Same Ssh Session