Misha Moroshko
Misha Moroshko

Reputation: 171399

How can I call a function before it is defined in Ruby?

In my seeds.rb file, I would like to have the following structure:

# Start of variables initialization
groups = ...
# End of variables initialization
check_data
save_data_in_database

# Functions go here
def check_data
  ...
end

def save_data_in_database
  ...
end

However, I got an error, because I call check_data before it is defined. Well, I can put the definition at the top of the file, but then the file will be less readable in my opinion. Is there another workaround?

Upvotes: 16

Views: 9707

Answers (5)

Brian Hempel
Brian Hempel

Reputation: 9094

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.

Upvotes: 30

steenslag
steenslag

Reputation: 80075

Andrew Grimm mentions END; there's also BEGIN

foo "hello"


BEGIN {
def foo (n)
  puts n
end}

You can't use this to initialize variables because the {} defines a local variable scope.

Upvotes: 13

Andrew Grimm
Andrew Grimm

Reputation: 81570

You could use END (upper case, not lower case)

END {
  # begin of variables initialization
  groups = ...
  # end of variables initialization
  check_data
  save_data_in_database
}

but that'd be a bit of a hack.

Basically, END code is run after all other code is run.

Edit: There's also Kernel#at_exit, (rdoc link)

Upvotes: 11

goodside
goodside

Reputation: 4629

Wrap your initial calls in a function and call that function at the end:

# begin of variables initialization
groups = ...
# end of variables initialization

def to_be_run_later
  check_data
  save_data_in_database
end

# functions go here
def check_data
  ...
end

def save_data_in_database
  ...
end

to_be_run_later

Upvotes: 1

Kleber S.
Kleber S.

Reputation: 8240

You could put the functions on another file and make a request on the top of the script.

Upvotes: 3

Related Questions