I've got a method in a class:
method options(*#opt) {
if !#!valid-options {
my $out = (cmd 'bin/md2html -h').out;
my #matches = $out ~~ m:g/\s'--'(<-[\s]>+)/;
for #matches -> $opt {
push #!valid-options, $opt[0].Str;
}
}
for #opt -> $opt {
when !($opt (elem) #!valid-options) {
warn "'$opt' is not a valid option";
}
push #!options, '--' ~ $opt;
}
}
The method checks that the options to see if they are valid and, if they are, places them into an attribute.
I pass args into the options method like this, as words:
$obj.options: <ftables ftasklists github>;
This works. But it got me wondering if it was possible pass in the options as named flags like this:
$obj.options: :ftables, :ftasklists, :github
But since I don't know all the command's options ahead of time, I'd need to generate the named arguments dynamically. Is this possible? I tried this but had no luck:
# create a signature
my #params = Parameter.new(name => ':$option', type => Bool, :!default);
my $sig = Signature.new(:#params);
my &blah = -> $sig { say 'this works too' } ;
&blah(:option1);
Currently, there is no way to do that, short of using EVAL.
You can add a slurpy hash to any sub signature to catch all unexpected named arguments:
sub foo(*%_) { .say for %_.keys }
foo :bar, :baz; # bar baz
Creating your own signatures at runtime may become possible / easier when the RakuAST has landed.
As seen in my code below, I am using apache to serve my Perl web server. I need Perl to have multple routes for my client as seen in my %dispatch. If I figure one out I'm sure the rest will be very similar. If we look at my Subroutine sub resp_index, how can I modify this to link to my index.html file located in my root: /var/www/perl directory?
/var/www/perl/perlServer.pl:
#!/usr/bin/perl
{
package MyWebServer;
use HTTP::Server::Simple::CGI;
use base qw(HTTP::Server::Simple::CGI);
my %dispatch = (
'/index.html' => \&resp_index,
# ...
);
sub handle_request {
my $self = shift;
my $cgi = shift;
my $path = $cgi->path_info();
my $handler = $dispatch{$path};
if (ref($handler) eq "CODE") {
print "HTTP/1.0 200 OK\r\n";
$handler->($cgi);
} else {
print "HTTP/1.0 404 Not found\r\n";
print $cgi->header,
$cgi->start_html('Not found'),
$cgi->h1('Not found'),
$cgi->end_html;
}
}
sub resp_index {
my $cgi = shift; # CGI.pm object
return if !ref $cgi;
my $who = $cgi->param('name');
print $cgi->header,
$cgi->start_html("index"),
$cgi-h1("THIS IS INDEX"),
$cgi->end_html;
}
}
my $pid = MyWebServer->new()->background();
print "Use 'kill $pid' to stop server.\n";
I think what you're asking is how do you serve a file from your web server? Open it and print it, like any other file.
use autodie;
sub resp_index {
my $cgi = shift;
return if !ref $cgi;
print $cgi->header;
open my $fh, "<", "/var/www/perl/index.html";
print <$fh>;
}
Unless this is an exercise, really, really, REALLY don't write your own web framework. It's going to be slow, buggy, and insecure. Consider a small routing framework like Dancer.
For example, mixing documents like index.html and executable code like perlServer.pl in the same directory invites a security hole. Executable code should be isolated in their own directory so they can be given wholly different permissions and stronger protection.
Let's talk about this line...
return if !ref $cgi;
This line is hiding an error. If your functions are passed the wrong argument, or no argument, it will silently return and you (or the person using this) will have no idea why nothing happened. This should be an error...
use Carp;
croak "resp_index() was not given a CGI object" if !ref $cgi;
...but really you should use one of the existing function signature modules such as Method::Signatures.
use Method::Signatures;
func resp_index(CGI $cgi) {
...
}
I'm trying to use Mediawiki, without getting the url to be like this.
https://roblox-network.com:80/tra/Special:RequestAccount
If i just remove :80 it works as it should.
Config file is below.
It should be a clean install, with restricted accounts.
But sadly i keep getting the :80 url many times, when i update every page.
So i have to remove :80 to update the pages.
<?php
error_reporting( E_ALL );
ini_set( 'display_errors', 1 );
# This file was automatically generated by the MediaWiki 1.17.0
# installer. If you make manual changes, please keep track in case you
# need to recreate them later.
#
# See includes/DefaultSettings.php for all configurable settings
# and their default values, but don't forget to make changes in _this_
# file, not there.
#
# Further documentation for configuration settings may be found at:
# http://www.mediawiki.org/wiki/Manual:Configuration_settings
# Protect against web entry
if ( !defined( 'MEDIAWIKI' ) ) {
exit;
}
## Uncomment this to disable output compression
# $wgDisableOutputCompression = true;
$wgSitename = 'TRA Wiki';
$wgMetaNamespace = "My_wiki";
$wgRightsPage = "YourWiki:Copyright";
$wgRightsText = "copyright Roblox Network";
## The URL base path to the directory containing the wiki;
## defaults for all runtime URL paths are based off of this.
## For more information on customizing the URLs please see:
## http://www.mediawiki.org/wiki/Manual:Short_URL
$wgScriptPath = '/tra';
$wgRunJobsAsync = false;
$wgArticlePath = $wgScriptPath.'/$1';
$wgScriptExtension = ".php";
## The relative URL path to the skins directory
$wgStylePath = "$wgScriptPath/skins";
## The relative URL path to the logo. Make sure you change this from the default,
## or else you'll overwrite your logo when you upgrade!
#$wgLogo = "$wgStylePath/common/images/wiki.png";
$wgLogo = "$wgStylePath/common/images/wiki.png";
## UPO means: this is also a user preference option
$wgEnableEmail = true;
$wgEnableUserEmail = true; # UPO
$wgEmergencyContact = 'info#roblox-network.com';
$wgPasswordSender = 'no-reply#roblox-network.com';
$wgEnotifUserTalk = false; # UPO
$wgEnotifWatchlist = false; # UPO
$wgEmailAuthentication = true;
## Database settings
$wgDBtype = "mysql";
$wgDBserver = 'mysql';
$wgDBname = 'REMOVED';
$wgDBuser = 'REMOVED';
$wgDBpassword = 'REMOVED';
# MySQL specific settings
$wgDBprefix = 'REMOVED';
# MySQL table options to use during installation or update
$wgDBTableOptions = "ENGINE=InnoDB, DEFAULT CHARSET=binary";
# Experimental charset support for MySQL 4.1/5.0.
$wgDBmysql5 = false;
## Shared memory settings
$wgMainCacheType = CACHE_NONE;
$wgMemCachedServers = array();
## To enable image uploads, make sure the 'images' directory
## is writable, then set this to true:
$wgEnableUploads = true;
$wgUseImageMagick = true;
$wgImageMagickConvertCommand = "/usr/bin/convert";
# InstantCommons allows wiki to use images from http://commons.wikimedia.org
$wgUseInstantCommons = false;
## If you use ImageMagick (or any other shell command) on a
## Linux server, this will need to be set to the name of an
## available UTF-8 locale
$wgShellLocale = "en_US.utf8";
## If you want to use image uploads under safe mode,
## create the directories images/archive, images/thumb and
## images/temp, and make them all writable. Then uncomment
## this, if it's not already uncommented:
#$wgHashedUploadDirectory = false;
## If you have the appropriate support software installed
## you can enable inline LaTeX equations:
$wgUseTeX = false;
## Set $wgCacheDirectory to a writable directory on the web server
## to make your wiki go slightly faster. The directory should not
## be publically accessible from the web.
#$wgCacheDirectory = "$IP/cache";
# Site language code, should be one of ./languages/Language(.*).php
$wgLanguageCode = 'en';
$wgSecretKey = "REMOVED";
# Site upgrade key. Must be set to a string (default provided) to turn on the
# web installer while LocalSettings.php is in place
$wgUpgradeKey = "REMOVED";
## Default skin: you can change the default skin. Use the internal symbolic
## names, ie 'standard', 'nostalgia', 'cologneblue', 'monobook', 'vector':
$wgDefaultSkin = "vector";
## For attaching licensing metadata to pages, and displaying an
## appropriate copyright notice / icon. GNU Free Documentation
## License and Creative Commons licenses are supported so far.
#$wgEnableCreativeCommonsRdf = true;
$wgRightsPage = "Roblox Network"; # Set to the title of a wiki page that describes your license/copyright
$wgRightsUrl = "https://roblox-network.com/terms/";
$wgRightsText = "";
$wgRightsIcon = "";
# $wgRightsCode = ""; # Not yet used
# Path to the GNU diff3 utility. Used for conflict resolution.
$wgDiff3 = "/usr/bin/diff3";
# Query string length limit for ResourceLoader. You should only set this if
# your web server has a query string length limit (then set it to that limit),
# or if you have suhosin.get.max_value_length set in php.ini (then set it to
# that value)
$wgResourceLoaderMaxQueryLength = -1;
# End of automatically generated settings.
# Add more configuration options below.
require_once "$IP/skins/Vector/Vector.php";
# ------------------ Below is the custom settings. ----------------------------
require_once "$IP/extensions/ConfirmAccount/ConfirmAccount.php";
require_once "$IP/extensions/SecurePoll/SecurePoll.php";
$wgShowSQLErrors = true;
$wgDebugDumpSql = true;
$wgShowDBErrorBacktrace = true;
$wgConfirmAccountContact = 'tra#roblox-network.com';
# ------------------ Below is the custom permissions. ----------------------------
$wgGroupPermissions['sysop']['securepoll-create-poll'] = true;
# ------------------ Below is loginform permissions. ----------------------------
$wgAccountRequestMinWords = 10;
$wgConfirmAccountRequestFormItems['Biography']['enabled'] = false;
$wgMakeUserPageFromBio = false;
$wgAutoWelcomeNewUsers = false;
$wgConfirmAccountRequestFormItems = array(
'UserName' => array( 'enabled' => true ),
'RealName' => array( 'enabled' => false ),
'Biography' => array( 'enabled' => false, 'minWords' => 50 ),
'AreasOfInterest' => array( 'enabled' => false ),
'CV' => array( 'enabled' => false ),
'Notes' => array( 'enabled' => true ),
'Links' => array( 'enabled' => false ),
'TermsOfService' => array( 'enabled' => true ),
);
# ------------------ Below is loginform restricted. ----------------------------
function efLoginFormMessage( &$template ) {
$template->set( 'header', "(For an account to edit articles with, contact Mr.Master3395, info#roblox-network.com )");
return true;
}
$wgHooks['UserLoginForm'][]='efLoginFormMessage';
# End of automatically generated settings.
# Add more configuration options below.
require_once "$IP/skins/Vector/Vector.php";
# Disable reading by anonymous users
$wgGroupPermissions['*']['read'] = true;
# But allow them to access the login page or else there will be no way to log in!
# (You also might want to add access to "Main Page", "Help:Contents", etc.)
$wgWhitelistRead = array ("Special:Userlogin");
# Disable anonymous editing
$wgGroupPermissions['*']['edit'] = false;
# Prevent new user registrations except by sysops
$wgGroupPermissions['*']['createaccount'] = false;
# ------------------ Below is Group Permissions. ----------------------------
$wgGroupPermissions['*']['edit'] = false;
$wgGroupPermissions['user']['edit'] = false;
$wgGroupPermissions['sysop']['edit'] = true;
# ------------------ Below is Uploads. ----------------------------
$wgUploadPath = "$wgScriptPath/uploads"; ## Wiki 1.5 defaults to /images, but allows more than just images
$wgUploadDirectory = "$IP/uploads"; ## Wiki 1.5 defaults to /images, but allows more than just images
## To enable image uploads, make sure the above '$wgUploadPath' directory is writable by Apache User or group.
## ''(i.e. chmod og+w uploads images)'' then the following should be true:
$wgEnableUploads = true;
$wgUseImageMagick = true;
$wgImageMagickConvertCommand = "/usr/bin/convert";
## If you want to use image uploads under safe mode, create the directories images/archive, images/thumb and
## images/temp, and make them all writable. Then uncomment this, if it's not already uncommented:
$wgHashedUploadDirectory = false;
# ------------------ Below is Uploads. ----------------------------
// Add just one filetype to the default array
$wgFileExtensions[] = 'pdf';
// Add several file types to the default array
$wgFileExtensions = array_merge(
$wgFileExtensions, array(
'pdf', 'ppt', 'jp2', 'webp', 'doc','docx', 'xls', 'xlsx'
)
);
// Override the default with a bundle of filetypes:
$wgFileExtensions = array(
'png', 'gif', 'jpg', 'jpeg', 'jp2', 'webp', 'ppt', 'pdf', 'psd',
'mp3', 'xls', 'xlsx', 'swf', 'doc','docx', 'odt', 'odc', 'odp',
'odg', 'mpp'
);
$wgMimeDetectorCommand = "file -bi";
# ------------------ Below is Google Analytics. ----------------------------
require_once "$IP/extensions/googleAnalytics/googleAnalytics.php";
// Replace xxxxxxx-x with YOUR GoogleAnalytics UA number
$wgGoogleAnalyticsAccount = 'UA-37062089-17';
// Add HTML code for any additional web analytics (can be used alone or with $wgGoogleAnalyticsAccount)
$wgGoogleAnalyticsOtherCode = '<script type="text/javascript" src="https://analytics.example.com/tracking.js"></script>';
// Optional configuration (for defaults see googleAnalytics.php)
// Store full IP address in Google Universal Analytics (see https://support.google.com/analytics/answer/2763052?hl=en for details)
$wgGoogleAnalyticsAnonymizeIP = false;
// Array with NUMERIC namespace IDs where web analytics code should NOT be included.
$wgGoogleAnalyticsIgnoreNsIDs = array(500);
// Array with page names (see magic word Extension:Google Analytics Integration) where web analytics code should NOT be included.
$wgGoogleAnalyticsIgnorePages = array('ArticleX', 'Foo:Bar');
// Array with special pages where web analytics code should NOT be included.
$wgGoogleAnalyticsIgnoreSpecials = array( 'Userlogin', 'Userlogout', 'Preferences', 'ChangePassword', 'OATH');
// Use 'noanalytics' permission to exclude specific user groups from web analytics, e.g.
$wgGroupPermissions['sysop']['noanalytics'] = true;
$wgGroupPermissions['bot']['noanalytics'] = true;
// To exclude all logged in users give 'noanalytics' permission to 'user' group, i.e.
$wgGroupPermissions['user']['noanalytics'] = true;
# ------------------ Below is Logo. ----------------------------
$wgLogoHD = array(
"1.5x" => "images/main/wiki.png",
# "2x" => "images/main/wiki.png"
);
# The URL path of the shortcut icon.
# #since 1.6
#/
#$wgFavicon = 'images/main/favicon.ico';
# The URL path of the icon for iPhone and iPod Touch web app bookmarks.
# Defaults to no icon.
# #since 1.12
#/
$wgAppleTouchIcon = false;
# ------------------ Below is Login Link. ----------------------------
$wgHooks['PersonalUrls'][] = 'onPersonalUrls';
function onPersonalUrls( array &$personal_urls, Title $title, SkinTemplate $skin ) {
// Add a link to Special:RequestAccount if a link exists for login
if ( isset( $personal_urls['login'] ) || isset( $personal_urls['anonlogin'] ) ) {
$personal_urls['createaccount'] = array(
'text' => wfMessage( 'requestaccount' )->text(),
'href' => SpecialPage::getTitleFor( 'RequestAccount' )->getFullURL()
);
}
return true;
}
Looks like your issue is connected to Confirm Account extension only, because all other links seems to be fine. I've noticed that $wgServer is missing from your config, so try to specify $wgServer variable in LocalSettings.php like this:
$wgServer = "https://roblox-network.com";
https is default port 443 and port 80 is reserved for http.
The problem indicates that port 80 is not handling SSL.
How can I load a OO-style module dynamically?
#!/usr/bin/env perl6
use v6;
my $r = prompt ':';
if $r {
require Text::CSV; # Error:
my $csv = Text::CSV.new; # Could not find symbol '&CSV'
} else {
require File::Temp <&tempfile>;
my ( $filename , $filehandle ) = tempfile; # this works
}
As explained in the perl6 doco here, you can dynamically load the module but;
To import symbols you must define them at compile time.
So, the code in the else clause works because of the explicit request to import <&tempfile>.
The closest thing to getting the code in the if clause to work that I can see is this (which is mostly taken from that earlier doco reference):
use v6.c ;
sub load-a-module($name) {
require ::($name) ;
my $instance = ::($name).new() ;
return $instance ;
}
my $module = "Text::CSV" ;
my $csv = load-a-module $module ;
say $csv.WHAT ;
# say $csv.^methods ; # if you really want to be convinced
# outputs: (CSV)
For debugging purposes I'd like to Access the lexical scope of different subroutines with a specific Attribute set. That works fine. I get a Problem when the first variable stores a string, then I get a empty string. I do something like this:
$pad = $cv->PADLIST; # $cv is the coderef to the sub
#scatchpad = $pad->ARRAY; # getting the scratchpad
#varnames = $scratchpad[0]->ARRAY; # getting the variablenames
#varcontents = $scratchpad[1]->ARRAY; # getting the Content from the vars
for (0 .. $#varnames) {
eval {
my $name = $varnames[$_]->PV;
my $content;
# following line matches numbers, works so far
$content = $varcontent[$_]->IVX if (scalar($varcontent[$_]) =~ /PVIV=/);
# should match strings, but does give me undef
$content = B::perlstring($varcontent[$_]->PV) if (scalar($varcontent[$_]) =~ /PV=/);
print "DEBUGGER> Local variable: ", $name, " = ", $content, "\n";
}; # there are Special vars that throw a error, but i don't care about them
}
Like I said in the comment the eval is to prevent the Errors from the B::Special objects in the scratchpad.
Output:
Local variable: $test = 42
Local variable: $text = 0
The first Output is okay, the second should Output "TEXT" instead of 0.
What am I doing wrong?
EDIT: With a little bit of coding I got all values of the variables , but not stored in the same indexes of #varnames and #varcontents. So now is the question how (in which order) the values are stored in #varcontents.
use strict;
use warnings;
use B;
sub testsub {
my $testvar1 = 42;
my $testvar2 = 21;
my $testvar3 = "testval3";
print "printtest1";
my $testvar4 = "testval4";
print "printtest2";
return "returnval";
}
no warnings "uninitialized";
my $coderef = \&testsub;
my $cv = B::svref_2object ( $coderef );
my $pad = $cv->PADLIST; # get scratchpad object
my #scratchpad = $pad->ARRAY;
my #varnames = $scratchpad[0]->ARRAY; # get varnames out of scratchpad
my #varcontents = $scratchpad[1]->ARRAY; # get content array out of scratchpad
my #vars; # array to store variable names adn "undef" for special objects (print-values, return-values, etc.)
for (0 .. $#varnames) {
eval { push #vars, $varnames[$_]->PV; };
if ($#) { push #vars, "undef"; }
}
my #cont; # array to store the content of the variables and special objects
for (0 .. $#varcontents) {
eval { push #cont, $varcontents[$_]->IV; };
eval { push #cont, $varcontents[$_]->PV; };
}
print $vars[$_], "\t\t\t", $cont[$_], "\n" for (0 .. $#cont);
EDIT2: Added runnable script to demonstrate the issue: Variablenames and variablevalues are not stored in the same index of the two Arrays (#varnames and #varcontents).