Ruby: How to Call Function Before It Is Defined

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:

  1. Extend a class.
  2. Add a singleton method to a class.
  3. Include a module in a class.
  4. 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



Leave a reply



Submit