So I have created an application in JRuby for the first time. Now I'm having trouble to understand how to finalize the application, ie. how to provide a .jar file that can be executed by the end user.
I'm aware of compiling to a .class file which can be invoked via the command line, but that's not very user friendly.
How do I provide an easy access to my application written in JRuby to an end user?
How do I provide an easy access to my application written in JRuby to
an end user?
You can try to install the rawr gem and see if you can get that to work.
1) To create all the necessary rawr files for your project(this is after you install the rawr gem):
~/jruby_programs$ mkdir proj1
~/jruby_programs$ cd proj1
~/jruby_programs/proj1$ rawr install
Then you get a bunch of output. That creates this directory structure:
../proj1
├── Rakefile
├── build_configuration.rb
├── lib
│ └── java
│ └── jruby-complete.jar
└── src
└── org
└── monkeybars
└── rawr
├── Main.java
└── Path.java
2) Put your source code in the src/ directory, e.g.
./src
├── hello_jruby.rb
└── org/
#hello_jruby.rb
puts 'hello'
require 'java'
java_import 'java.util.TreeSet'
set = TreeSet.new
set.add "foo"
set.add "Bar"
set.add "baz"
set.each do |v|
puts "value: #{v}"
end
3) Create the jar file:
~/jruby_programs/proj1$ rake rawr:jar
I initially used rake rawr:base_jar because that is what the rawr docs indicate you should do, but that wouldn't work for me. When I executed the jar file(see next step), I kept getting the error:
Exception in thread "main" java.lang.NoClassDefFoundError:
org/jruby/RubyInstanceConfig at
org.monkeybars.rawr.Main.main(Main.java:21) Caused by:
java.lang.ClassNotFoundException: org.jruby.RubyInstanceConfig
4) Execute the jar file:
~/jruby_programs/proj1$ java -jar package/jar/proj1.jar
This is my output:
Add 'src/' to $:
hello
value: Bar
value: baz
value: foo
Unfortuantely, I don't know how to get rid of that first line. $: is a ruby global variable whose synonym is $LOAD_PATH. Adding the following to the top of hello_jruby.rb didn't work:
$LOAD_PATH << '/src'
Here are the tweaks I had to make to the build_configurationl.rb file(you only have to uncomment sections if the defaults don't work for you):
# Generated by Rawr version 1.7.0
configuration do |c|
# The name for your resulting application file (e.g., if the project_name is 'foo' then you'll get foo.jar, foo.exe, etc.)
# default value: "proj1"
#
#c.project_name = "proj1"
# Undocumented option 'output_dir'
# default value: "package"
#
#c.output_dir = "package"
# The type of executable to create (console or gui)
# default value: "gui"
#
c.executable_type = "console"
# The main ruby file to invoke, minus the .rb extension
# default value: "main"
#
c.main_ruby_file = 'hello_jruby'
# The fully-qualified name of the main Java file used to initiate the application.
# default value: "org.monkeybars.rawr.Main"
#
#c.main_java_file = "org.monkeybars.rawr.Main"
# A list of directories where source files reside
# default value: ["src"]
#
#c.source_dirs = ["src"]
# A list of regexps of files to exclude
# default value: []
#
#c.source_exclude_filter = []
# The base directory that holds Mirah files, or subdirectories with Mirah files.
# default value: "src"
#
#c.mirah_source_root = "src"
# Whether Ruby source files should be compiled into .class files. Setting this to true currently breaks packaging
# default value: false
#
#c.compile_ruby_files = false
# A list of individual Java library files to include.
# default value: []
#
#c.java_lib_files = []
# A list of directories for rawr to include . All files in the given directories get bundled up.
# default value: ["lib/java"]
#
#c.java_lib_dirs = ["lib/java"]
# A list of files that will be copied into the `<output_dir>/jar` folder. Note that the files maintain their directory path when copied.
# default value: []
#
#c.files_to_copy = []
# Undocumented option 'source_jvm_version'
# default value: 1.7
#
c.source_jvm_version = 1.6
# Undocumented option 'target_jvm_version'
# default value: 1.7
#
c.target_jvm_version = 1.6
# Undocumented option 'jvm_arguments'
# default value: ""
#
#c.jvm_arguments = ""
# Undocumented option 'java_library_path'
# default value: ""
#
#c.java_library_path = ""
# Undocumented option 'extra_user_jars'
# default value: {}
#
#c.extra_user_jars[:data] = { :directory => 'data/images/png',
# :location_in_jar => 'images',
# :exclude => /*.bak$/ }
# Undocumented option 'verbose'
# default value: false
#
#c.verbose = false
# Undocumented option 'mac_do_not_generate_plist'
# default value: false
#
#c.mac_do_not_generate_plist = false
# working directory specified in plist file
# default value: "$APP_PACKAGE"
#
#c.mac_plist_working_directory = "$APP_PACKAGE"
# Undocumented option 'mac_icon_path'
# default value: nil
#
#c.mac_icon_path = nil
# Undocumented option 'windows_icon_path'
# default value: nil
#
#c.windows_icon_path = nil
end
Related
Here we go again!
I got lots of folders with contain many files in a directory. e.g.: index, controller, layout files etc.
My task is to iterate through each and every folders/files and try to find some specific keywords.
I got the answer using bash command.
grep '$this->' -R *.php -n > result.txt
It works but only pulling out one line at the time and just a broken syntax as I need to grab the whole code if the code is in multiple lines. The result will also can print out the paths/folders including which line details. I looked over the net and were suggested to use Dir.glob
note: I prefer using ruby since It will be a lot more confused to me with other language. I am new to ruby and that the only language that I am learning as from now.
Thanks
# Recursively get absolute paths of the files with specified extension in specified directory
#
# #param ext [String] extension of the files to look for (default - any extension)
# #param pwd [String] absolute or relative path where to look for the files (default - current directory)
# #param list [Array<String>] used to recursively store absolute paths (default - [])
# #return [Array<String>] Array array of absolute paths of files in the directory with specified extension
def files(ext = '.*', pwd = Dir.pwd, list = [])
Dir[File.expand_path(File.join(pwd, '*'))].each do |path|
if File.directory?(path)
files(ext, path, list)
else
list << path if File.extname(path) =~ Regexp.new(ext, true)
end
end
list
end
# Find all the files with provided extension in provided directory which contain keyword
#
# #param keyword [String] keyword to look for
# #param ext [String] extension of the files to look for (default - any extension)
# #param pwd [String] absolute or relative path where to look for the files (default - current directory)
# #param ignorecase [Bool] ignore case when searching for keyword if set to true (default - true)
# #return [Hash<String, Array<Integer>>] hash of the files which contain provided keyword.
# Key - file absolute path, value - array of number lines where the keyword is present
def find_keywords(keyword, ext = '.*', pwd = Dir.pwd, ignorecase = true)
results = {}
files(ext, pwd).each do |file|
File.readlines(file).each_with_index do |line, line_number|
if line =~ Regexp.new(Regexp.escape(keyword), ignorecase)
results[file] ||= []
results[file] << line_number + 1
end
end
end
results
end
p find_keywords('$thIs->', '.php')
#=> { "~/path/main.php" => [87, 99, 126], "~/path/config/sample.php" => [24], }
In development my all of my images, CSS and JS are loading fine. In production, my CSS and JS are loading fine. Background images load fine through CSS, and images written as:
image_tag "foo.png"
also load fine and show a fingerprint. However, images written as:
image_tag #test_question.question.image
are not fingerprinted in production (the image name is recorded in the database). However, this works fine in development.
In development I see:
<img src="/assets/picture1-a2bac24ba737cf267b5cc29f9fdaea33.jpg">
In production I see:
<img src="/images/picture1.jpg">
Assets including the images are compiled and fingerprinted in appropriate directories on my production server, they are just not fingerprinted or called correctly in the view. I am using Rails 4.2, nginx and unicorn, and deploying with Capistrano 3.2.
Edit:
I have image subdirectories. The following is in my initializers:
initializers/assets.rb
Dir.glob("#{Rails.root}/app/assets/images/**/").each do |path|
Rails.application.config.assets.paths << path
end
When I comment this out, the behaviour is the same in development as in production. So, I suppose that the problem is that this code is not working / being read in the production environment. Any suggestions?
environments/production.rb
config.cache_classes = true
config.eager_load = true
config.consider_all_requests_local = false
config.action_controller.perform_caching = true
config.assets.js_compressor = :uglifier
config.assets.css_compressor = :sass
config.assets.compile = false
config.assets.digest = true
config.assets.version = Digest::MD5.hexdigest(Date.new.to_s)
config.assets.initialize_on_precompile = true
config.i18n.fallbacks = true
deploy.rb
lock '3.2.1'
set :application, 'foobar'
set :deploy_user, 'deploy'
# Default branch is :master
# ask :branch, proc { `git rev-parse --abbrev-ref HEAD`.chomp }.call
# Default deploy_to directory is /var/www/my_app
# set :deploy_to, '/var/www/my_app'
set :deploy_to, "/home/#{fetch(:deploy_user)}/apps/#{fetch(:full_app_name)}"
# Default value for :scm is :git
set :scm, :git
set :repo_url, 'git#github.com:foobar/baz.git'
set :rbenv_type, :system
set :rbenv_ruby, '2.2.2'
set :rbenv_prefix, "RBENV_ROOT=#{fetch(:rbenv_path)} RBENV_VERSION=#{fetch(:rbenv_ruby)} #{fetch(:rbenv_path)}/bin/rbenv exec"
set :rbenv_map_bins, %w{rake gem bundle ruby rails}
set :keep_releases, 2
set :linked_files, %w{config/database.yml config/secrets.yml config/application.yml}
set :linked_dirs, %w{bin log tmp/pids tmp/cache tmp/sockets vendor/bundle public/system}
# Default value for :format is :pretty
set :format, :pretty
# what specs should be run before deployment is allowed to
# continue, see lib/capistrano/tasks/run_tests.cap
set :tests, []
# which config files should be copied by deploy:setup_config
# see documentation in lib/capistrano/tasks/setup_config.cap
# for details of operations
set(:config_files, %w(
nginx.conf
log_rotation
monit
unicorn.rb
unicorn_init.sh
application.yml
database.yml
))
# which config files should be made executable after copying
# by deploy:setup_config
set(:executable_config_files, %w(
unicorn_init.sh
))
# files which need to be symlinked to other parts of the
# filesystem. For example nginx virtualhosts, log rotation
# init scripts etc.
set(:symlinks, [
{
source: "nginx.conf",
link: "/etc/nginx/sites-enabled/{{full_app_name}}"
},
{
source: "unicorn_init.sh",
link: "/etc/init.d/unicorn_{{full_app_name}}"
},
{
source: "log_rotation",
link: "/etc/logrotate.d/{{full_app_name}}"
},
{
source: "monit",
link: "/etc/monit/conf.d/{{full_app_name}}.conf"
}
])
namespace :deploy do
before :deploy, "deploy:check_revision"
# compile assets locally then rsync
#after 'deploy:symlink:shared', 'deploy:compile_assets_locally'
#after :finishing, 'deploy:cleanup'
# remove the default nginx configuration as it will tend
# to conflict with our configs.
before 'deploy:setup_config', 'nginx:remove_default_vhost'
# reload nginx to it will pick up any modified vhosts from
# setup_config
after 'deploy:setup_config', 'nginx:reload'
# Restart monit so it will pick up any monit configurations
# we've added
after 'deploy:setup_config', 'monit:restart'
# As of Capistrano 3.1, the `deploy:restart` task is not called
# automatically.
after 'deploy:publishing', 'deploy:restart'
after "deploy:restart", "deploy:cleanup"
end
I really can't see what the problem is here. Any suggestions?
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Closed 9 years ago.
Improve this question
I am using emacs on Mac Os X and I installed aspell with homebrew. I accidentally added a wrong word to my "private dictionary", but where is that dictionary? How can I open it and see what I have added in there?
I found a similar question here (How to remove an entry from ispell private dictionary?) but I couldn't find the directories they mentioned. I found one aspell folder at \usr\local\Cellar\aspell\, but I still can't find which one is the private dictionary.
Search for a file ending in .pws -- it will probably look something like this .aspell.en.pws for English.
You can also run something like this to see where everything is located -- just change the path to wherever your own aspell executable is located:
/Users/HOME/.0.data/.0.emacs/elpa/bin/aspell --lang=en dump config
If you want to change things, you can create an aspell.conf and put it inside the etc folder, which should be in the same set of directories near to where the aspell executable is located. I actually had to create the etc folder and the aspell.conf because the make process of a generic installation did not create that folder. Running the above command-line will also tell you the location where aspell looks for the aspell.conf file.
Sample aspell.conf: I only use Spanish and English -- the default on my setup is the latter -- borrowed (and modified from): https://github.com/jone/dotfiles/blob/master/aspell.conf
# /Users/HOME/.0.data/.0.emacs/elpa/bin/aspell --lang=en dump config
# conf (string)
# main configuration file
# default: aspell.conf
# home-dir (string)
# location for personal files
# default: <$HOME|./> = /Users/jone
# home-dir $HOME/Library/Preferences/aspell
home-dir /Users/HOME/.0.data/.0.emacs
# personal (string)
# personal dictionary file name
# default: .aspell.<lang>.pws = .aspell.de_CH.pws
personal .aspell.en.pws
# conf-dir (string)
# location of main configuration file
# default: <prefix:etc> = /usr/local/etc
# data-dir (string)
# location of language data files
# default: <prefix:lib/aspell-0.60> = /usr/local/lib/aspell-0.60
# data-dir /usr/local/lib/aspell-0.60
# dict-alias (list)
# create dictionary aliases
# dict-dir (string)
# location of the main word list
# default: <data-dir> = /usr/local/lib/aspell-0.60
# dict-dir /usr/local/lib/aspell-0.60
# encoding (string)
# encoding to expect data to be in
# default: !encoding = UTF-8
# filter (list)
# add or removes a filter
# filter-path (list)
# path(s) aspell looks for filters
# mode (string)
# filter mode
# default: url
# mode tex
# extra-dicts (list)
# extra dictionaries to use
# ignore (integer)
# ignore words <= n chars
# default: 1
# ignore-case (boolean)
# ignore case when checking words
# default: false
# ignore-repl (boolean)
# ignore commands to store replacement pairs
# default: false
ignore-repl false
# keyboard (string)
# keyboard definition to use for typo analysis
# default: standard
# lang (string)
# language code
# default: <language-tag> = de_CH
# local-data-dir (string)
# location of local language data files
# default: <actual-dict-dir> = /usr/local/lib/aspell-0.60/
# master (string)
# base name of the main dictionary to use
# default: <lang> = de_CH
# normalize (boolean)
# enable Unicode normalization
# default: true
# norm-required (boolean)
# Unicode normalization required for current lang
# default: false
# norm-form (string)
# Unicode normalization form: none, nfd, nfc, comp
# default: nfc
# norm-strict (boolean)
# avoid lossy conversions when normalization
# default: false
# per-conf (string)
# personal configuration file
# default: .aspell.conf
# prefix (string)
# prefix directory
# default: /usr/local
# repl (string)
# replacements list file name
# default: .aspell.<lang>.prepl = .aspell.de_CH.prepl
# run-together (boolean)
# consider run-together words legal
# default: false
# run-together-limit (integer)
# maximum number that can be strung together
# default: 2
# run-together-min (integer)
# minimal length of interior words
# default: 3
# save-repl (boolean)
# save replacement pairs on save all
# default: true
# set-prefix (boolean)
# set the prefix based on executable location
# default: true
# size (string)
# size of the word list
# default: +60
# sug-mode (string)
# suggestion mode
# default: normal
# sug-edit-dist (integer)
# edit distance to use, override sug-mode default
# default: 1
# sug-typo-analysis (boolean)
# use typo analysis, override sug-mode default
# default: true
# sug-repl-table (boolean)
# use replacement tables, override sug-mode default
# default: true
# sug-split-char (list)
# characters to insert when a word is split
# use-other-dicts (boolean)
# use personal, replacement & session dictionaries
# default: true
# variety (list)
# extra information for the word list
# warn (boolean)
# enable warnings
# default: true
# affix-compress (boolean)
# use affix compression when creating dictionaries
# default: false
# clean-affixes (boolean)
# remove invalid affix flags
# default: true
# clean-words (boolean)
# attempts to clean words so that they are valid
# default: false
# invisible-soundslike (boolean)
# compute soundslike on demand rather than storing
# default: false
# partially-expand (boolean)
# partially expand affixes for better suggestions
# default: false
# skip-invalid-words (boolean)
# skip invalid words
# default: true
# validate-affixes (boolean)
# check if affix flags are valid
# default: true
# validate-words (boolean)
# check if words are valid
# default: true
# backup (boolean)
# create a backup file by appending ".bak"
# default: true
# byte-offsets (boolean)
# use byte offsets instead of character offsets
# default: false
# guess (boolean)
# create missing root/affix combinations
# default: false
# keymapping (string)
# keymapping for check mode: "aspell" or "ispell"
# default: aspell
# reverse (boolean)
# reverse the order of the suggest list
# default: false
# suggest (boolean)
# suggest possible replacements
# default: true
# time (boolean)
# time load time and suggest time in pipe mode
# default: false
#######################################################################
#
# Filter: context
# experimental filter for hiding delimited contexts
#
# configured as follows:
# f-context-delimiters (list)
# context delimiters (separated by spaces)
# f-context-visible-first (boolean)
# swaps visible and invisible text
# default: false
#######################################################################
#
# Filter: email
# filter for skipping quoted text in email messages
#
# configured as follows:
# f-email-quote (list)
# email quote characters
# f-email-margin (integer)
# num chars that can appear before the quote char
# default: 10
#######################################################################
#
# Filter: html
# filter for dealing with HTML documents
#
# configured as follows:
# f-html-check (list)
# HTML attributes to always check
# f-html-skip (list)
# HTML tags to always skip the contents of
#######################################################################
#
# Filter: sgml
# filter for dealing with generic SGML/XML documents
#
# configured as follows:
# f-sgml-check (list)
# SGML attributes to always check
# f-sgml-skip (list)
# SGML tags to always skip the contents of
#######################################################################
#
# Filter: tex
# filter for dealing with TeX/LaTeX documents
#
# configured as follows:
# f-tex-check-comments (boolean)
# check TeX comments
# default: false
# f-tex-command (list)
# TeX commands
#######################################################################
#
# Filter: texinfo
# filter for dealing with Texinfo documents
#
# configured as follows:
# f-texinfo-ignore (list)
# Texinfo commands to ignore the parameters of
# f-texinfo-ignore-env (list)
# Texinfo environments to ignore
These are my notes for installing aspell on Windows and OSX:
OSX -- To dump the aspell configuration in OSX type:
# /Users/HOME/.0.data/.0.emacs/elpa/bin/aspell --lang=en dump config
The aspell.conf goes into the .../etc directory
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
OSX -- ASPELL -- Binary
* unpack aspell-0.60.6.tar.gz
* cd over to the root directory of the unpacked source
PATH=/usr/bin:/usr/sbin:/bin:/sbin ./configure \
--prefix=$HOME/.0.data/.0.emacs/elpa
make
sudo make install
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
OSX -- ASPELL -- DICTIONARY -- English
* unpack aspell6-en-7.1-0.tar.bz2
* cd over to the root directory of the unpacked source
./configure \
--vars PATH=$PATH:/Users/HOME/.0.data/.0.emacs/elpa/bin
make
sudo make install
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
OSX -- ASPELL -- DICTIONARY -- Spanish
* unpack aspell6-es-1.11-2.tar.bz2
* cd over to the root directory of the unpacked source
./configure \
--vars PATH=$PATH:/Users/HOME/.0.data/.0.emacs/elpa/bin
make
sudo make install
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Windows XP -- install:
BASE: Aspell-0-50-3-3-Setup.exe
English: Aspell-en-0.50-2-3.exe
Spanish: Aspell-es-0.50-2-3.exe
Windows XP -- create an aspell.conf file at the following location:
c:/Program Files/Aspell/aspell.conf
# aspell.conf
# To dump the configuration, type into the terminal:
# "c:/Program Files/Aspell/bin/aspell.exe" --lang=en dump config
home-dir y:\.0.emacs
personal .aspell.en.pws
repl .aspell.en.prepl
ok so I can get to active admin on local and my site just fine - within active admin I have the options to select from Pins or Users (my two models) on local, can see all of the pins and users in the db just fine. However, live (heroku) I can access active admin barnpix.com/admin and clicking on pins works just fine ..however when I click users I get a generic heroku error... please help why does this work in local but not live?
Omrails::Application.routes.draw do
get "pages/tagz"
get "pages/about"
get "posts/show"
get "posts/destroy"
root :to => 'pins#index'
get 'tags/:tag' , to: 'pins#index', as: :tag
get "posts", to: "posts#index"
resources :posts
resources :pins
get "users/show"
devise_for :users
match 'users/:id' => 'users#show', as: :user
ActiveAdmin.routes(self)
devise_for :admin_users, ActiveAdmin::Devise.config
ActiveAdmin.routes(self)
devise_for :views
ActiveAdmin.routes(self)
ActiveAdmin.setup do |config|
# == Site Title
#
# Set the title that is displayed on the main layout
# for each of the active admin pages.
#
config.site_title = "BarnPix.com"
# Set the link url for the title. For example, to take
# users to your main site. Defaults to no link.
#
config.site_title_link = "http://www.barnpix.com"
# Set an optional image to be displayed for the header
# instead of a string (overrides :site_title)
#
# Note: Recommended image height is 21px to properly fit in the header
#
# config.site_title_image = "/images/logo.png"
# == Default Namespace
#
# Set the default namespace each administration resource
# will be added to.
#
# eg:
# config.default_namespace = :hello_world
#
# This will create resources in the HelloWorld module and
# will namespace routes to /hello_world/*
#
# To set no namespace by default, use:
# config.default_namespace = false
#
# Default:
# config.default_namespace = :admin
#
# You can customize the settings for each namespace by using
# a namespace block. For example, to change the site title
# within a namespace:
#
# config.namespace :admin do |admin|
# admin.site_title = "Custom Admin Title"
# end
#
# This will ONLY change the title for the admin section. Other
# namespaces will continue to use the main "site_title" configuration.
# == User Authentication
#
# Active Admin will automatically call an authentication
# method in a before filter of all controller actions to
# ensure that there is a currently logged in admin user.
#
# This setting changes the method which Active Admin calls
# within the controller.
config.authentication_method = :authenticate_admin_user!
# == Current User
#
# Active Admin will associate actions with the current
# user performing them.
#
# This setting changes the method which Active Admin calls
# to return the currently logged in user.
config.current_user_method = :current_admin_user
# == Logging Out
#
# Active Admin displays a logout link on each screen. These
# settings configure the location and method used for the link.
#
# This setting changes the path where the link points to. If it's
# a string, the strings is used as the path. If it's a Symbol, we
# will call the method to return the path.
#
# Default:
config.logout_link_path = :destroy_admin_user_session_path
# This setting changes the http method used when rendering the
# link. For example :get, :delete, :put, etc..
#
# Default:
# config.logout_link_method = :get
# == Root
#
# Set the action to call for the root path. You can set different
# roots for each namespace.
#
# Default:
# config.root_to = 'dashboard#index'
# == Admin Comments
#
# Admin comments allow you to add comments to any model for admin use.
# Admin comments are enabled by default.
#
# Default:
# config.allow_comments = true
#
# You can turn them on and off for any given namespace by using a
# namespace config block.
#
# Eg:
# config.namespace :without_comments do |without_comments|
# without_comments.allow_comments = false
# end
# == Batch Actions
#
# Enable and disable Batch Actions
#
config.batch_actions = true
# == Controller Filters
#
# You can add before, after and around filters to all of your
# Active Admin resources and pages from here.
#
# config.before_filter :do_something_awesome
# == Register Stylesheets & Javascripts
#
# We recommend using the built in Active Admin layout and loading
# up your own stylesheets / javascripts to customize the look
# and feel.
#
# To load a stylesheet:
# config.register_stylesheet 'my_stylesheet.css'
# You can provide an options hash for more control, which is passed along to stylesheet_link_tag():
# config.register_stylesheet 'my_print_stylesheet.css', :media => :print
#
# To load a javascript file:
# config.register_javascript 'my_javascript.js'
# == CSV options
#
# Set the CSV builder separator (default is ",")
# config.csv_column_separator = ','
#
# Set the CSV builder options (default is {})
# config.csv_options = {}
# == Menu System
#
# You can add a navigation menu to be used in your application, or configure a provided menu
#
# To change the default utility navigation to show a link to your website & a logout btn
#
# config.namespace :admin do |admin|
# admin.build_menu :utility_navigation do |menu|
# menu.add label: "My Great Website", url: "http://www.mygreatwebsite.com", html_options: { target: :blank }
# admin.add_logout_button_to_menu menu
# end
# end
#
# If you wanted to add a static menu item to the default menu provided:
#
# config.namespace :admin do |admin|
# admin.build_menu :default do |menu|
# menu.add label: "My Great Website", url: "http://www.mygreatwebsite.com", html_options: { target: :blank }
# end
# end
# == Download Links
#
# You can disable download links on resource listing pages,
# or customize the formats shown per namespace/globally
#
# To disable/customize for the :admin namespace:
#
# config.namespace :admin do |admin|
#
# # Disable the links entirely
# admin.download_links = false
#
# # Only show XML & PDF options
# admin.download_links = [:xml, :pdf]
#
# end
# == Pagination
#
# Pagination is enabled by default for all resources.
# You can control the default per page count for all resources here.
#
#config.default_per_page = 30
# == Filters
#
# By default the index screen includes a “Filters” sidebar on the right
# hand side with a filter for each attribute of the registered model.
# You can enable or disable them for all resources here.
#
# config.filters = true
end
Context
I am auto-requiring all files in a directory structure via
# base.rb
dir = File.dirname(__FILE__)
path = File.join(dir, '**', '*.rb')
Dir[path].each { |file| require File.expand_path(file, __FILE__) }
and am calling this snippet through a require statement in a separate file, api.rb.
Problem
This code snippet includes itself (base.rb) as well as api.rb.
Question
Is there a 'clean' way to do this type of auto-requiring while dynamically avoiding including the file that has called the auto-require'er (i.e. api.rb)?
Remember that when you require a file identified by a certain path more than once each subsequent call to require will return false and the file won't be reevaluated. As a result if your base.rb, which requires everything else, is itself required, further attepts to require it should not lead to a reevaluation.
Let's demonstrate it using an example. Create a lib directory with 3 files inside.
# lib/a.rb
require 'base'
puts :a
# lib/b.rb
require 'base'
puts :b
# lib/base.rb
$counter ||= 0
puts "Evaluated base.rb #{$counter += 1} times"
dir = File.dirname(__FILE__)
path = File.join(dir, '**', '*.rb')
Dir[path].each { |file| require File.expand_path file }
Execute lib/base.rb directly. base.rb will be evaluated twice: firstly, when it's executed directly; secondly, when it's required by a.rb. Notice, that it is not evaluated when it's required from b.rb.
$ ruby -I lib lib/base.rb
Evaluated base.rb 1 times
Evaluated base.rb 2 times
a
b
Compare with requireing it. Now base.rb is evaluated once only, because attempts to require it in a.rb and b.rb were preceded by having the file required using the command line -r switch.
$ ruby -I lib -r base -e 'puts :ok'
Evaluated base.rb 1 times
a
b
ok
Kernel.caller
returns the current execution stack as an array of strings. You can avoid
calling require on filenames which you find in that array. Multiple files with
the same basename would trip this up. I don't see a way to get a more precise
list of ancestor files.
$ head *.rb
==> A.rb <==
require 'base'
puts :A
==> B.rb <==
require 'base'
puts :B
==> CA.rb <==
require 'base'
puts :CA
==> base.rb <==
dir = File.dirname(__FILE__)
path = File.join(dir, '**', '*.rb')
required = caller.map { |frame| /^(.+):\d+:in `require'$/.match(frame) and File.basename $1 }.compact
Dir[path].each { |file| required.include?(File.basename file) or require File.expand_path file }
$ ruby A.rb
B
CA
A
$ ruby B.rb
A
CA
B
$ ruby CA.rb
A
B
CA
$ ruby base.rb
B
CA
A
$