I've recently updated to Ruby 1.9.2 (RVM), Sinatra 1.1 and Passenger 3.0.0. I have a simple application composed of:
# config.ru
require 'rubygems'
require 'sinatra'
require 'app.rb'
run Sinatra::Application
# app.rb
require 'rubygems'
require 'sinatra'
get '/' do
erb :index
end
If I run the application from the terminal using ruby app.rb everythign launches as expected. However, with Passenger I get: no such file to load -- app.rb. I have other Rails applications running fine with the setup, and have setup the document root to a sub public directory. Any ideas how to fix this? Thanks!
I had the same problem here:
# config.ru
require 'rubygems'
require 'sinatra'
require File.dirname(__FILE__) + "/app.rb"
run Sinatra::Application
Managed to fix the issue. Figured out for some reason the config.ru requires the include to be specified relative to the current directory. The modified file is:
# config.ru
require 'rubygems'
require 'sinatra'
require './app.rb'
run Sinatra::Application
Related
I have installed perlbrew and installed two Perls with it.
Now I am trying to separate libraries for modules I install with cpanm.
I want (if possible) to switch to one Perl (within Perlbrew) (for example: 5.22.4) and once I call cpanm install Some::Module the module will be installed in the separate library, related only to this Perl.
Then, in the script, I would like to have like the example below:
#!/usr/bin/env perl
use strict;
use Some::Module;
print "Content-type:text/html\n\n";
print "Works!";
and that's it. No any other use lib 'path'; or so.
I tried to use perlbrew lib create perl-5.22.4#somename and then switch to it.
Then call cpanm install Some::Module and I see the result at the location ~/.perlbrew/perl-5.22.4#somename/lib/perl5/Some/Module.pm, but when I call my script from a browser I see Error 500 and the logs say "missing module Some::Module, check #INC etc..."
What I also found that if I move the ~/.perlbrew/perl-5.22.4#somename/lib/perl5/Some/Module.pm to ~/perl5/perlbrew/perls/perl-5.22.4/lib/5.22.4/Some/Module.pm or to /home/arseniigorkin/perl5/perlbrew/perls/perl-5.22.4/lib/site_perl/5.22.4/x86_64-linux/Some/Module.pm then the script works. And Perl 5.22.4 (in our example) has its own library without need to use use lib 'path';
But, how to set up Perlbrew to switch cpanm automatically to this directory?
What I was also trying: cpanm install -l /home/arseniigorkin/perl5/perlbrew/perls/perl-5.22.4/lib/site_perl/5.22.4/x86_64-linux Some::Module to specify the target lib dir, but it creates the next tree under /home/arseniigorkin/perl5/perlbrew/perls/perl-5.22.4/lib/site_perl/5.22.4/x86_64-linux instead:
lib
perl5
Some
Module.pm
x86_64-linux
auto
[.....]
.meta
[.....]
perllocal.pod
install.pm
man
man3
[.....]
and, sadly, the script throws Error 500.
So, is there a possibility to omit use lib 'path'; in the script, switching between multiple Perl versions in Perlbrew?
This all happens on Ubuntu 22.04.
Update:
When switching to perl-5.22.4#somename and installing Some::Module via cpanm the module appears under the ~/.perlbrew/perl-5.22.4#somename/lib/perl5/Some/Module.pm as mentioned above, but the CGI script fails with Error 500.
However, when I execute the next command: perlbrew list-modules it shows Some::Module as installed under the current Perl (which I am switched to). So, this is a dissonance: Perlbrew "sees" the module under the specific Perl, but the CGI script cannot "see" this module under the same Perl.
Update 2:
here is the output of the perlbrew info:
Current perl:
Name: perl-5.22.4#somename
Path: /home/username/perl5/perlbrew/perls/perl-5.22.4/bin/perl
Config: -de -Dprefix=/home/username/perl5/perlbrew/perls/perl-5.22.4 -Dusesitecustomize -Aeval:scriptdir=/home/username/perl5/perlbrew/perls/perl-5.22.4/bin
Compiled at: Nov 10 2022 23:26:53
perlbrew:
version: 0.96
ENV:
PERLBREW_ROOT: /home/username/perl5/perlbrew
PERLBREW_HOME: /home/username/.perlbrew
PERLBREW_PATH: /home/username/.perlbrew/libs/perl-5.22.4#somename/bin:/home/username/perl5/perlbrew/bin:/home/arseniigorkin/perl5/perlbrew/perls/perl-5.22.4/bin
PERLBREW_MANPATH: /home/username/.perlbrew/libs/perl-5.22.4#somename/man:/home/username/perl5/perlbrew/perls/perl-5.22.4/man
Update 3:
The dirs permissions for the libs:
and
#terry0its is the name of the library (in the example I called it #somename.
Update 4:
Printing vars:
PERL_MB_OPT
PERL_MM_OPT
PERL5LIB
PATH
PERL_LOCAL_LIB_ROOT
with the script:
#!/usr/bin/env perl
print "Content-type:text/html\n\n";
print <<HTML;
Vars:<br>
PERL_MB_OPT = #{[$ENV{"PERL_MB_OPT"}]}<br>
PERL_MM_OPT = #{[$ENV{"PERL_MM_OPT"}]}<br>
PERL5LIB = #{[$ENV{"PERL5LIB"}]}<br>
PATH = #{[$ENV{"PATH"}]}<br>
PERL_LOCAL_LIB_ROOT = #{[$ENV{"PERL_LOCAL_LIB_ROOT"}]}<br>
HTML
In the web browser:
Vars:
PERL_MB_OPT =
PERL_MM_OPT =
PERL5LIB =
PATH = /home/username/.perlbrew/libs/perl-5.22.4#terry0its/bin:/home/username/perl5/perlbrew/bin:/home/username/perl5/perlbrew/perls/perl-5.22.4/bin:/root/Komodo IDE/bin:/home/username/anaconda3/condabin:/root/Komodo IDE/bin:/home/username/pycharm/bin:/home/username/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/snap/bin:/home/username/.local/share/JetBrains/Toolbox/scripts
PERL_LOCAL_LIB_ROOT =
With the terminal:
Content-type:text/html
Vars:
PERL_MB_OPT = --install_base
/home/username/.perlbrew/libs/perl-5.22.4#terry0its
PERL_MM_OPT =
INSTALL_BASE=/home/username/.perlbrew/libs/perl-5.22.4#terry0its
PERL5LIB =
/home/username/.perlbrew/libs/perl-5.22.4#terry0its/lib/perl5
PATH =
/home/username/.perlbrew/libs/perl-5.22.4#terry0its/bin:/home/username/perl5/perlbrew/bin:/home/username/perl5/perlbrew/perls/perl-5.22.4/bin:/root/Komodo
IDE/bin:/home/username/anaconda3/condabin:/root/Komodo
IDE/bin:/home/username/pycharm/bin:/home/username/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/snap/bin:/home/username/.local/share/JetBrains/Toolbox/scripts
PERL_LOCAL_LIB_ROOT =
/home/username/.perlbrew/libs/perl-5.22.4#terry0its
Update 5:
When I switch to a pure perl-5.22.4 (without external lib, like #terry0its) I see the next output for the same scripts (after the restart of the server):
In the web browser:
Vars:
PERL_MB_OPT =
PERL_MM_OPT =
PERL5LIB =
PATH = /home/username/anaconda3/condabin:/home/username/perl5/perlbrew/bin:/home/username/perl5/perlbrew/perls/perl-5.22.4/bin:/root/Komodo IDE/bin:/home/arseniigorkin/perl5/bin:/home/username/pycharm/bin:/home/username/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/snap/bin:/home/username/.local/share/JetBrains/Toolbox/scripts
PERL_LOCAL_LIB_ROOT =
With the terminal:
Content-type:text/html
Vars:
PERL_MB_OPT --install_base "/home/username/perl5"
PERL_MM_OPT = INSTALL_BASE=/home/username/perl5
PERL5LIB =
PATH =
/home/username/anaconda3/condabin:/home/username/perl5/perlbrew/bin:/home/username/perl5/perlbrew/perls/perl-5.22.4/bin:/root/Komodo IDE/bin:/home/username/perl5/bin:/home/username/pycharm/bin:/home/username/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/snap/bin:/home/username/.local/share/JetBrains/Toolbox/scripts
PERL_LOCAL_LIB_ROOT =
/home/username/perl5
The issue was related to Apache2 server-specific behavior with ENV variables.
It strips off some environment variables so they are undefined in your CGI scripts.
To have them in the CGI script you simply have to add PassEnv PERL5LIB into your host conf file and restart the server. Then, voila - you have PERL5LIB showing correctly in the output of $ENV{PERL5LIB} all across your site.
The example code:
<Directory "/home/user/someproject/server/www/public_html/cgi-bin">
AllowOverride All
Options None
Require all granted
Options +ExecCGI
PassEnv PERL5LIB
AddHandler cgi-script .cgi .pl
</Directory>
So, to use Perlbrew and easily switching between Perls and to have automatically handling all your libs (incl. externally created with perlbrew create lib somename) you have to PASS the PERl5LIB environment to your CGI scripts explicitly in the Apache configuration file for your host.
Do not forget to check if your mod_env is enabled in the httpd.conf (main Apache configuration file) as LoadModule env_module modules/mod_env.so (it must be uncommented).
I hope it will help others to handle easily their Perl libraries of perlbrew with Apache2 server.
Also, the module mod_env allows us to add custom environment variables, that we will be able to use all across the host or a server (it depends on where you put it in - inside the main conf file, your host file, or just into .htaccess for a particular dir(s) or even page(s)).
perlbrew does two things:
Makes installing Perl a little bit easier.
Manipulate the PATH of a shell that loads it.
The CGI script isn't launched by a shell.
First, you shouldn't be using PERL5LIB. Why install a custom perl using perlbrew and then try to cause it to use modules installed by another perl? This is nothing but bad. Unset PERL5LIB.
And with PERL5LIB unset, you shouldn't be using PERL_MB_OPT and PERL_MM_OPT either. You need to let the modules get installed where perl will find them.
So start by cleaning out the mess. Make sure PERL5LIB, PERL_MB_OPT and PERL_MM_OPT aren't set anywhere. You may to need reinstall the modules if they were installed in a weird place.
Now, using the correct perl will load the modules installed by that perl.
So what left is ensuring that we're using the correct perl. You use /usr/bin/env to locate perl. Does it makes sense for Apache's PATH to control which perl your application uses? Probably not.
What I would do is create an alias in perlbrew for your project.
perlbrew alias create perl-5.22.4#somename myproject
Then use the following shebang line:
#!/home/username/perl5/perlbrew/perls/myproject/bin/perl
That will allow you use to control which build of perl your project uses using
perlbrew alias create -f ... myproject
This works using symlinks, not PATH manipulation, so it works from anywhere, not just shells using perlbrew.
I have a test suite with hundreds of tests for a perl module I've yet to release which is a command line interface. Since it is a command line interface, the tests (until possibly now) are all written to drop code into a template and then call the template script using a system call.
I recently added an optional dependency on a 3rd party module that's not a part of core perl. I know my module works whether that module is installed or not because I have a computer with it installed and one without and the module works without error in each case. However, I'd like to be able to write a test to confirm that my module will work when the 3rd party module is absent - and I'd like that test to work even if the 3rd party module is installed, but behave as if it wasn't.
Ideally, I could use the structure I've put in place for testing which makes a system call to a template script. I know I could write a separate test script that manipulates #INC in the BEGIN block, imports the particular methods that use the module, and call them like a unit test. But I would like to know if there's a way I can use the test structure I've already got all my other tests using, which is to make a system call.
So is there a way to exclude a module from being imported via a perl command line option? I've tried -M-Module, but the code use Module still imports the module.
Incidentally, my module uses the 3rd party module inside an eval, which is how I made it optional.
I wrote Test::Without::Module for this exact case. It works by modifying #INC to prevent loading of modules that you name. For testing, you could either run the test from the command line:
perl -MTest::Without::Module=Some::Module -w -Iblib/lib t/SomeModule.t
Or allow/disallow loading the module from within your test suite:
use Test::Without::Module qw( My::Module );
# Now, loading of My::Module fails :
eval { require My::Module; };
warn $# if $#;
# Now it works again
eval q{ no Test::Without::Module qw( My::Module ) };
eval { require My::Module; };
print "Found My::Module" unless $#;
Running the Catalyst internal server, located at scripts/MyApp_server.pm, I receive the following error. Is there any one who can help me in this regard?
I have not changed any of the files created by catalyst.pl. I just have run the catalyst.pl MyApp and then run scripts/MyApp_server.pl -r for testing whether Catalyst works or not. This is the only things I have done!
I have reinstalled Catalyst and its dependent modules several times by using either yum and cpan. But it doesn't work again.
Thanks!
THE ERROR MESSAGE:
Can't use an undefined value as a HASH reference at /usr/local/share/perl5/Catalyst.pm line 2681.
BEGIN failed--compilation aborted at /home/Ali/Lab/WEB/catalyst/MyApp3/script/../lib/MyApp3.pm line 20.
Compilation failed in require at /usr/local/lib/perl5/Class/MOP/Method/Wrapped.pm line 50
The codes around line 2681 in /usr/local/share/perl5/Catalyst.pm are as below:
sub setup_home {
my ( $class, $home ) = #_;
if ( my $env = Catalyst::Utils::env_value( $class, 'HOME' ) ) {
$home = $env;
}
$home ||= Catalyst::Utils::home($class);
if ($home) {
#I remember recently being scolded for assigning config values like this
$class->config->{home} ||= $home; # THIS IS LINE 2681
$class->config->{root} ||= Path::Class::Dir->new($home)->subdir('root');
}
}
The content of the lib/MyApp.pm is as below:
package MyApp;
use Moose;
use namespace::autoclean;
use Catalyst::Runtime 5.80;
# Set flags and add plugins for the application
#
# -Debug: activates the debug mode for very useful log messages
# ConfigLoader: will load the configuration from a Config::General file in the
# application's home directory
# Static::Simple: will serve static files from the application's root
# directory
use Catalyst qw/
-Debug
ConfigLoader
Static::Simple
/;
extends 'Catalyst';
our $VERSION = '0.01';
$VERSION = eval $VERSION;
# Configure the application.
#
# Note that settings in myapp.conf (or other external
# configuration file that you set up manually) take precedence
# over this when using ConfigLoader. Thus configuration
# details given here can function as a default configuration,
# with an external configuration file acting as an override for
# local deployment.
__PACKAGE__->config(
name => 'MyApp',
# Disable deprecated behavior needed by old applications
disable_component_resolution_regex_fallback => 1,
);
# Start the application
__PACKAGE__->setup();
=head1 NAME
MyApp - Catalyst based application
=head1 SYNOPSIS
script/myapp_server.pl
=head1 DESCRIPTION
[enter your description here]
=head1 SEE ALSO
L<MyApp::Controller::Root>, L<Catalyst>
=head1 AUTHOR
Ali Basirat
=head1 LICENSE
This library is free software. You can redistribute it and/or modify
it under the same terms as Perl itself.
=cut
1;
This isn't a definitive answer, but hopefully will help a little.
You've either got an undefined $class or $class->config (more likely), although how I can't say. Perhaps the ConfigLoader hasn't worked.
Re-installing things blindly seldom helps and the problem could be due to any module in the dependency list. If there was a specific problem installing a module then there would have been an error and we could have worked on that.
So - using yum install cpanm and local::lib - I'm not sure what the packages are called on Red Hat, but it should be easy enough to find out.
OK - now create a new directory somewhere suitable.
mkdir /home/Devt/catalyst_test
cd /home/Devt/catalyst_test
eval $(perl -Mlocal::lib=./perllib)
echo $PERL5LIB
# You should see your current directory mentioned in PERL5LIB
cpanm Catalyst
cpanm Catalyst::Helper
catalyst.pl MyApp
cd MyApp/
perl Makefile.PL
./script/myapp_server.pl
# Opens up a server on port 3000
What local::lib is doing is setting up the paths to install everything locally (in perllib) - you can see the environment variables it sets up by running it without the eval.
perl -Mlocal::lib=./perllib
See the docs for how to add it to a bash login script. I just redirect the output to a file and source it when I'm working on a project (I use one perllib per project).
Then, cpanm is smart enough to use this local directory to install all the bits you need.
If this doesn't work, the problem is probably due to something you've manually installed in /usr/local/. Take a backup of the various perl-related lib dirs in /usr/local/ and then clean them out. Run cpanm again (checking local::lib paths are setup first) and see if the versions it downloads work.
The above should work - it's exactly what I did 10 minutes ago.
The whole idea of this is to create a separate installation of all your perl libraries for this project - that way if you upgrade anything it only affects the current installation.
I'm trying to organize a few perl scripts in a way so I can reuse some functions between them. The directive 'require' however doesn't seem to work when the script is ran as CGI under Apache. I've tried this:
require "common.pl"
but it doesn't work under Apache.
I've also tried this:
use File::Basename;
use Cwd qw(abs_path);
require abs_path(dirname($0))."/common.pl";
which works both on the command line and under Apache on my local server but not on my webhost's server.
Do you know what the proper way to 'require' a perl script is so it works on both the command line and under Apache?
Edit: I'm looking for a way (not necessarily using 'require') to make the functions defined in 'common.pl' available to the script calling this here. So basically I have 2 scripts 'foo.pl' and 'bar.pl' from which I'd like to reuse the functions written in 'common.pl'. What is the right way to do that in Perl? 'require' works fine on the command line, but not under Apache... I have no control over %INC, and I can't hardcode the full path to 'common.pl'.
I can't hardcode the path to 'common.pl' because this set of scripts has to run on 3 different servers, each having a different absolute path for it.
Edit2: The error message I get happens when running using mod_perl (I was mistakenly stating this was all happening when running under Apache/cgi, but I had mod_perl on on one of the 3 setups, the other 2 setups were running scripts as regular cgi scripts, and the error I was seeing was unrelated to the 'require' statement, which works fine under regular cgi). The error is as follows:
Can't locate common.pl in #INC (#INC contains: /Library/Perl/Updates/5.10.0/darwin-thread-multi-2level /Library/Perl/Updates/5.10.0 /System/Library/Perl/5.10.0/darwin-thread-multi-2level /System/Library/Perl/5.10.0 /Library/Perl/5.10.0/darwin-thread-multi-2level /Library/Perl/5.10.0 /Network/Library/Perl/5.10.0/darwin-thread-multi-2level /Network/Library/Perl/5.10.0 /Network/Library/Perl /System/Library/Perl/Extras/5.10.0/darwin-thread-multi-2level /System/Library/Perl/Extras/5.10.0 . /usr) at /.../check.pl
Configuring software to suit different deployments is a fact of life. Sometimes 'magic' can help, but often it can lead to inpenetrable problems as well.
Do you have control over the environment? I would set environment variables (http://httpd.apache.org/docs/current/mod/mod_env.html) in your Apache config and use them as the path in your require.
Why would hardcoding three different paths be a problem?
use Sys::Hostname;
my $host = hostname();
$host eq 'foo' and push #INC, '/foo';
$host eq 'bar' and push #INC, '/bar';
$host eq 'baz' and push #INC, '/baz';
require 'common.pl';
Granted, it's not the most elegant solution, but if it works...
Having problems getting CPAN to work with a MiniCPAN repository from within a script (aim is a code deployment system to build local modules together with modules from CPAN, install to a local-lib, and then sync out to servers)
$HOME/.cpan/CPAN/MyConfig.pm exists, with urllist set to ['file:///home/user/minicpan/']
The (non-CPAN) module distribution was injected sucessfully into the minicpan repo, and file exists: e.g. /home/user/minicpan/authors/U/US/USER/My-Module-0.01.tar.gz.
The author is in .../01mailrc.txt.gz, module is in .../modules/02packages.details.txt.gz
The module is found and installs via the cpan shell.
Fails through following code:
CPAN::HandleConfig->load;
CPAN::Shell::setup_output;
CPAN::Index->reload;
# dumping config here shows urllist set correctly,
# and config exactly the same as through shell
use Data::Dumper;
$Data::Dumper::Sortkeys = 1;
print Dumper($CPAN::Config);
CPAN::Shell->install("My::Module");
Either doesn't find module ("Cannot install My::Module, don't know what it is.") or claims is up to date (My::Module is up to date (0.01))
Module is not installed in the local-lib (and not anywhere else on machine, e.g. in /usr/...)
Local-lib environment variables are set via
eval $(perl -I$HOME/foo/lib/perl5 -Mlocal::lib=$HOME/locallib) in bash profile
After getting either error (including 'Module is up to date'), a normal 'install' in the shell works without force, as does perl -MCPAN -e "install My::Module", so I presume it's the config not set correctly, but the CPAN.pm docs are rather hard to follow...
(CPAN.pm is v1.9402)
try :
#!/usr/bin/perl -w
system <cpan install My::Module>