Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > writing get_script as an external routine callable by C

Reply
Thread Tools

writing get_script as an external routine callable by C

 
 
Franken Sense
Guest
Posts: n/a
 
      05-12-2009

With forum help, I've been able to do pretty good damage with using perl
for input. It's *so much* easier than my alternatives with compiled
languages that I really feel like I'm in touch with the virtue of laziness.

I'm simply too immature with perl to, say, populate a binary tree with the
data or do many of the things that I can do with compiled languages, once I
have the data where I want it. This is, I think, a nice final touch by
Mark Krahn:

#!/usr/bin/perl
# perl m13.pl
use warnings;
use strict;

# open input file
my $filename = 'text43.txt';
open(my $fh, '<', $filename) or
die "cannot open $filename for reading: $!";

# open output file
my $filename2 = 'outfile16.txt';
open(my $gh, '>', $filename2) or
die "cannot open $filename2 for writing: $!";

local $/="";

while ( <$fh> )
{
my ( $verse, @s ) = split;
my $script = join ' ', @s;
print $gh "$verse $script\n";
}


# close input and output files
close($gh) or die("Error closing $filename2: $!");
close($fh) or die("Error closing $filename: $!");

# abridged output:

44:004:002 Being grieved that they taught the people, and preached through
Jesus the resurrection from the dead.
44:004:003 And they laid hands on them, and put them in hold unto the next
day: for it was now eventide.
44:004:004 Howbeit many of them which heard the word believed; and the
number of the men was about five thousand.
44:004:005 And it came to pass on the morrow, that their rulers, and
elders, and scribes,


So now I want main to have to call a routine to get the next $verse and
$script.

@anything = get_script( $verse, \@s)

sub get_script
{

my ( $verse, @s ) = split;
my $script = join ' ', @s;
return something;
}

Not exactly beautiful code, but my first efforts rarely look nice. The
reference for this in the camel book is §6 : Passing References. p 224

Then there's the matter of calling a perl subroutine from C.

#include <EXTERN.h>
#include <perl.h>

static PerlInterpreter *my_perl;

int main(int argc, char **argv, char ** env)
{
char *args[] = {Null};
my_perl = perl_alloc();
perl_construct(my_perl);
perl_parse(my_perl, NULL, argc, argv, NULL);
call_argv("get_script", args);
perl_destruct(my_perl);
perl_free(my_perl);

return 0;
}

The reference here is §21 of the camel book, p. 540.

Does any of this look close?
--
Frank

Oh, What Doesn't Kill You Can Have Lingering Aftereffects!
~~ Al Franken,
 
Reply With Quote
 
 
 
 
Franken Sense
Guest
Posts: n/a
 
      05-14-2009
In Dread Ink, the Grave Hand of Ben Morrow Did Inscribe:

> Quoth http://www.velocityreviews.com/forums/(E-Mail Removed)d:


[snipped and reordered]
>> The reference here is §21 of the camel book, p. 540.
>>
>> Does any of this look close?

>
> Reasonably so. You should be using perldoc perlembed as your reference
> rather than the Camel book: the Camel was published shortly before the
> release of perl 5.6.0, and a lot has changed since then. Most
> importantly, you are missing PERL_SYS_INIT3 and PERL_SYS_TERM which must
> be called first and last respectively.
>
> You should also be aware that there are a number of undocumented
> initializations that may or may not be necessary depending on your
> platform. You can print a C file which ought to reproduce your current
> perl binary by running
>
> perl -MExtUtils::Miniperl -ewritemain
>
> Perl embedding is quite subtle, and I would not really recommend it
> until you are familiar with writing XS. In order to do anything useful
> with the embedded interpreter, you will need to know how to use the perl
> API to get at and interpret the Perl values in the program.
>
> You are passing main's argc/v to perl_parse, which means your program
> will need to be called with the same command-line arguments as perl
> would be. If you want your C program to run a particular Perl program,
> you will need to create your own argv array to pass to perl_parse. Note
> that you must still pass main's argc/v/env to PERL_SYS_INIT3.
>
> If you really want to try this, you need to start by reading perlembed
> and perlcall, and then probably perlapi and perlguts.


With that amount of reading in order to embed perl into C, I'll put that on
the reading list for my next injury. Thank you.

> You haven't yet explained why you're trying to do this. Given your
> inexperience with perl, it's almost certainly going to be easier to
> stick with writing in one language at a time for now.
>


I've been reading §6. The semantics section does not include an example
with inputs. I think the best example is in Tricks with Parameter Lists
with something like:

sub get_script {
my($verse, $script) =@_;
....

I was thinking that I would try to--thereafter--get these data in a hash,
which is close as I'm going to able to come to getting them into a tree. I
suppose a hash is a tree, why not?

Anyways, below I see
sub configuration {
my %options = @_;
....

> If you actually want to pass a ref, your sub needs to look more like
>
> sub get_script {
> my ($verse, $sref) = @_;
> my $script = join " ", @$sref;


Ok, so a little more of the same terminology with @_ . How does one
pronounce this symbol?

If main were going to open my_file and get the $verse and $script that
we've been using and calls get_script with

getscript($verse, $script);

and instead have:

sub get_script {
my %options = @_;

, what will %options look like? Could you print the hash in alphabetic
order? Can you search in blindingly-fast time for a particular chapter and
verse, indicated by the obvious interpretation of $verse?
--
Frank

When you encounter seemingly good advice that contradicts other seemingly
good advice, ignore them both.
~~ Al Franken,
 
Reply With Quote
 
 
 
 
Jürgen Exner
Guest
Posts: n/a
 
      05-14-2009
Franken Sense <(E-Mail Removed)> wrote:
>If main were going to open my_file and get the $verse and $script that
>we've been using and calls get_script with
>
>getscript($verse, $script);
>
>and instead have:
>
>sub get_script {
> my %options = @_;
>
>, what will %options look like?


You are passing a list of two scalars to the sub, these are copied into
a hash, which would mean you got a hash with one element, the value of
$verse being the hash key and the value of $script being the hash value
for this element.

>Could you print the hash in alphabetic order?


You need to be more specific. Do you want to print the keys or the
values sorted by the alphabetical order of the keys or by the
alpabetical order of the values? Either one is easy enough.

>Can you search in blindingly-fast time for a particular chapter and
>verse, indicated by the obvious interpretation of $verse?


Can you reconstruct $verse (i.e. the hash key) from that particular
chapter and verse? If yes, then access will be O(1) in the general case.
You can't get any faster than that.

If you cannot reconstruct the hash key based on chapter and verse and
searching for that is _the_ critical operation in your program, then I
would suggest to redesign the datastructure such that a combination of
chapter and verse can be used as the key.

Or use a database system instead.

jue
 
Reply With Quote
 
Jürgen Exner
Guest
Posts: n/a
 
      05-14-2009
Ben Morrow <(E-Mail Removed)> wrote:
>Quoth (E-Mail Removed)d:
>> getscript($verse, $script);
>>
>> and instead have:
>>
>> sub get_script {
>> my %options = @_;

>
>Umm, I don't think I'm understanding what you're doing here, or you're
>not. In general it's best to post complete (but short) programs that you
>have actually tested, as it makes things clearer.
>
>If you have
>
> sub get_script {
> my %options = @_;
>
>then it expects to be called like
>
> get_script(verse => $verse, script => $script);
>
>and you will then end up with
>
> $options{verse} = $verse;
> $options{script} = $script;
>
>If you call it as you have above, you will have a single key which is
>the string value of $verse, and its corresponding value will be $script.
>I suspect this isn't what you want.


Actually, I think (but I may be wrong) that's exactly what he's looking
for.

>If you are trying to build a hash up over successive calls to
>get_script, you will need to either declare the hash outside the sub


Good point, missed that one.
And if he makes %options global, then there is little point in calling
that sub, he could just as well do a direct
%options = ($verse -> $script);
instead of the sub call.

> In any case, you will want to assign the
>provided key and value to different variables, and then insert them into
>the hash: assigning to a hash like that replaces everything in it.


Another good catch! So do a
$options{$verse} = $script;
instead of that sub call.

jue
 
Reply With Quote
 
Franken Sense
Guest
Posts: n/a
 
      05-14-2009
In Dread Ink, the Grave Hand of Jürgen Exner Did Inscribe:

> Ben Morrow <(E-Mail Removed)> wrote:
>>Quoth (E-Mail Removed)d:
>>> getscript($verse, $script);
>>>
>>> and instead have:
>>>
>>> sub get_script {
>>> my %options = @_;

>>
>>Umm, I don't think I'm understanding what you're doing here, or you're
>>not. In general it's best to post complete (but short) programs that you
>>have actually tested, as it makes things clearer.


Testing now.
>>
>>If you have
>>
>> sub get_script {
>> my %options = @_;
>>
>>then it expects to be called like
>>
>> get_script(verse => $verse, script => $script);
>>
>>and you will then end up with
>>
>> $options{verse} = $verse;
>> $options{script} = $script;
>>
>>If you call it as you have above, you will have a single key which is
>>the string value of $verse, and its corresponding value will be $script.
>>I suspect this isn't what you want.

>
> Actually, I think (but I may be wrong) that's exactly what he's looking
> for.
>
>>If you are trying to build a hash up over successive calls to
>>get_script, you will need to either declare the hash outside the sub

>
> Good point, missed that one.
> And if he makes %options global, then there is little point in calling
> that sub, he could just as well do a direct
> %options = ($verse -> $script);
> instead of the sub call.
>
>> In any case, you will want to assign the
>>provided key and value to different variables, and then insert them into
>>the hash: assigning to a hash like that replaces everything in it.

>
> Another good catch! So do a
> $options{$verse} = $script;
> instead of that sub call.
>
> jue


I'll see if I can put that all together; I think I can.

I switched data sets to the second part of the old testament that you might
find at gutenberg.org. I think this is a solid choice, as I didn't want to
get to hung up on the specific form I ran into on my first sortie with
computer exegetics, namely Acts.

I really like the look of these new data:

Canticle of Canticles Chapter 4


Christ sets forth the graces of his spouse: and declares his love for
her.

4:1. How beautiful art thou, my love, how beautiful art thou! thy eyes
are doves' eyes, besides what is hid within. Thy hair is as flocks of
goats, which come up from mount Galaad.

How beautiful art thou. . .Christ again praises the beauties of his
church, which through the whole of this chapter are exemplified by a
variety of metaphors, setting forth her purity, her simplicity, and her
stability.

....

Gosh, I'm gonna have to look at nuns in a different light now. Anyways,
the form here is basically the same: if a line is a scripture, it begins
with a number that will serve as a key for searches.

This is the latest version:

#!/usr/bin/perl
# perl bb2.pl
use warnings;
use strict;

# open input file
my $filename = 'ot4.txt';
open(my $fh, '<', $filename) or
die "cannot open $filename for reading: $!";

# open output file
my $filename2 = 'outfile16.txt';
open(my $gh, '>', $filename2) or
die "cannot open $filename2 for writing: $!";

local $/="";

while ( <$fh> )
{
my ( $verse, @s ) = split;
my $script = join ' ', @s;
print "$verse $script\n";
print $gh "$verse $script\n";
}


# close input and output files
close($gh) or die("Error closing $filename2: $!");
close($fh) or die("Error closing $filename: $!");

# abridged output:

C:\MinGW\source>perl bb1.pl
Canticle of Canticles Chapter 2
Christ caresses his spouse: he invites her to him.
2:1. I am the flower of the field, and the lily of the valleys.
I am the flower of the field. . .Christ professes himself the flower of
mankind,
yea, the Lord of all creatures: and, ver. 2, declares the excellence of
his spo

....
bite and destroy the vines.
2:16. My beloved to me, and I to him who feedeth among the lilies,
2:17. Till the day break, and the shadows retire. Return: be like, my
beloved, t
o a roe, or to a young hart upon the mountains of Bether.

C:\MinGW\source>
--
Frank

The biases the media has are much bigger than conservative or liberal.
They're about getting ratings, about making money, about doing stories that
are easy to cover.
~~ Al Franken,
 
Reply With Quote
 
Franken Sense
Guest
Posts: n/a
 
      05-14-2009
In Dread Ink, the Grave Hand of Franken Sense Did Inscribe:

> Gosh, I'm gonna have to look at nuns in a different light now.


http://lomas-assault.net/usenet/(!!hail%20mary).jpg


> Anyways,
> the form here is basically the same: if a line is a scripture, it begins
> with a number that will serve as a key for searches.


I'm bombing out here on something I think is easy. How do I populate
@books with book1.txt that looks like

Book of Psalms
Book of Proverbs
Ecclesiastes
Solomon's Canticle of Canticles
Book of Wisdom
...
Prophecy of Zacharias
Prophecy of Malachias
First Book of Machabees
Second Book of Machabees

#!/usr/bin/perl
# perl bb3.pl
use warnings;
use strict;

# open input file
my $filename = 'book1.txt';
open(my $fh, '<', $filename) or
die "cannot open $filename for reading: $!";

# open output file
my $filename2 = 'outfile16.txt';
open(my $gh, '>', $filename2) or
die "cannot open $filename2 for writing: $!";

my @books;

while ( <$fh> )
{
chomp;



}


# close input and output files
close($gh) or die("Error closing $filename2: $!");
close($fh) or die("Error closing $filename: $!");
--
Frank

I said that Sean Hannity took residence up Newt Gingrich's butt from 94 to
98. I got that from British intelligence. It turns out he only took up
residence in 95.
~~ Al Franken
 
Reply With Quote
 
Uri Guttman
Guest
Posts: n/a
 
      05-14-2009
>>>>> "BM" == Ben Morrow <(E-Mail Removed)> writes:

>> my $filename = 'book1.txt';
>> open(my $fh, '<', $filename) or
>> die "cannot open $filename for reading: $!";
>> my @books;


BM> chomp( my @books = <$fh> );

BM> If you prefer, you can expand that to three statements:

BM> my @books;
BM> @books = <$fh>;
BM> chomp @books;

BM> You can also use File::Slurp::read_file, which will handle opening the
BM> file, chomping the lines and closing the file for you.

read_file doesn't (yet) chomp lines. that option is in the todo
list. but it does make it easier to read in a file as lines. this should
work fine:

use File::Slurp ;
chomp( my @books = read_file( $file_name ) ) ;

uri

--
Uri Guttman ------ (E-Mail Removed) -------- http://www.sysarch.com --
----- Perl Code Review , Architecture, Development, Training, Support ------
--------- Free Perl Training --- http://perlhunter.com/college.html ---------
--------- Gourmet Hot Cocoa Mix ---- http://bestfriendscocoa.com ---------
 
Reply With Quote
 
Franken Sense
Guest
Posts: n/a
 
      05-15-2009
In Dread Ink, the Grave Hand of Jürgen Exner Did Inscribe:

> Ben Morrow <(E-Mail Removed)> wrote:


>> In any case, you will want to assign the
>>provided key and value to different variables, and then insert them into
>>the hash: assigning to a hash like that replaces everything in it.


I don't quite understand this last sentence.
>
> Another good catch! So do a
> $options{$verse} = $script;
> instead of that sub call.
>
> jue


Ok, so far so good. Here's what this looks like now:

#!/usr/bin/perl
# perl bb6.pl
use warnings;
use strict;

# open input files
my $filename = 'book1.txt';
open(my $fh, '<', $filename) or
die "cannot open $filename for reading: $!";

my $filename3 = 'ot5.txt';
open(my $hh, '<', $filename3) or
die "cannot open $filename3 for reading: $!";

# open output file
my $filename2 = 'outfile16.txt';
open(my $gh, '>', $filename2) or
die "cannot open $filename2 for writing: $!";

my @books;
my %Scripts;
my %comments;

@books = <$fh>;
chomp @books;
print "@books\n";

local $/="";

while ( <$hh> )
{
my @s = split /\s+/, $_;
my $verse = $s[0];
my $script = join(' ', @s[1..$#s]);
$Scripts{$verse} = $script;
}

print %Scripts;
my @keys = keys %Scripts;
print @keys;

# close input and output files

close($hh) or die("Error closing $filename3: $!");
close($gh) or die("Error closing $filename2: $!");
close($fh) or die("Error closing $filename: $!");

Abridged output:
Book of Psalms Book of Proverbs Ecclesiastes Solomon's Canticle of
Canticles Book of Wisdom Ecclesiasticus Prophecy of Isaias Prophecy
of Jeremias Lamentations of Jeremias Prophecy of Baruch Prophecy of
....
My son, sow not evils in the furrows of injustice, and thou shalt not reap
them sevenfold.Whofirst hath perfect knowledge of her. . .Christ was the
first that had perfect knowledge of heavenly wisdom.50:8.And as the rainbow
giving light in bright clouds, and as the flower of roses in the days of
the spring, and as the lilies that are on the brink of the water, and as
the sweet smelling frankincense in the time of summer.39:21.All the works
of the Lord are exceeding good.4:11.And thou shalt be as the obedient son
of the most High, and he will have mercy on thee more than a mother.29:25.A
sinner that transgresseth the commandment of the Lord, shall fall into an
....
49:7.16:11.It46:14.46:2.30:13.38:30.26:6.25:17.8:2 0.
4:19.9:19.51:28.38:32.35:17.9:20.23:34.25:25.40:23 .25:1
..38:6.25:12.15:1.1:26.23:13.2:5.12:19.10:4.20:19. 18:1.19:
8.49:12.14:10.21:26.3:26.Jesus3:31.10:11.34:19.34: 18.21:1
4.11:13.7:33.1:9.24:23.31:15.46:9.12:18.3:8.23:1.2 4:20.4:
4.15:3.25:14.20:22.17:30.41:1.40:6.50:2.1:17.God's 2:15.32:
19.26:27.15:20.26:22.38:27.45:17.24:7.6:20.26:23.1 3:16.47:
4.4:3.30:5.11:25.Wise24:32.16:24.38:21.3:30.45:20. 40:4.33:


It appears true that a hash is not ordered like a binary tree.

Where I'm hung up now is in creating a control that separates comments from
scriptures. Scriptures begin with numbers, comments don't. So I was
poking around for a function like isdigit and couldn't find anything.

If comments are to be a hash, then they need something to key on, and all
that comes to mind is the natural numbers. Here's what the pseudosource
looks like:

$my $counter = 0;
while ( <$hh> )
{
my @s = split /\s+/, $_;

if (s[0] is a number)

my $verse = $s[0];
my $script = join(' ', @s[1..$#s]);
$Scripts{$verse} = $script;
else
$counter++;
my $comment = join(' ', @s);
%comments($counter) = $comment;
}

Fishing for tips. I like Ecclesiastes and the sad jews in general like
Janeane Garafalo, Al Franken and Jon Stewart.
--
Frank

My father grew up in the Great Depression - his mother's.
~~ Al Franken
 
Reply With Quote
 
Franken Sense
Guest
Posts: n/a
 
      05-15-2009
In Dread Ink, the Grave Hand of Uri Guttman Did Inscribe:

>>>>>> "BM" == Ben Morrow <(E-Mail Removed)> writes:

>
> >> my $filename = 'book1.txt';
> >> open(my $fh, '<', $filename) or
> >> die "cannot open $filename for reading: $!";
> >> my @books;

>
> BM> chomp( my @books = <$fh> );
>
> BM> If you prefer, you can expand that to three statements:
>
> BM> my @books;
> BM> @books = <$fh>;
> BM> chomp @books;
>
> BM> You can also use File::Slurp::read_file, which will handle opening the
> BM> file, chomping the lines and closing the file for you.
>
> read_file doesn't (yet) chomp lines. that option is in the todo
> list. but it does make it easier to read in a file as lines. this should
> work fine:
>
> use File::Slurp ;
> chomp( my @books = read_file( $file_name ) ) ;
>
> uri



C:\MinGW\source>perldoc File::Slurp
No documentation found for "File::Slurp".

C:\MinGW\source>
--
Frank

...................... o _______________ _,
` Good Morning! , /\_ _| | .-'_|
`................, _\__`[_______________| _| (_|
] [ \, ][ ][ (_|
 
Reply With Quote
 
Jürgen Exner
Guest
Posts: n/a
 
      05-15-2009
Franken Sense <(E-Mail Removed)> wrote:
>Where I'm hung up now is in creating a control that separates comments from
>scriptures. Scriptures begin with numbers, comments don't. So I was
>poking around for a function like isdigit and couldn't find anything.


perldoc -q number:
How do I determine whether a scalar is a number/whole/integer/float?

jue
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
writing get_script() Franken Sense C Programming 29 05-26-2009 11:34 PM
writing get_script() Frank Seitz Perl Misc 38 05-12-2009 06:15 AM
Making Non Callable Objects Callable exiquio Python 2 10-07-2008 06:02 PM
dlopen() within a JNI-callable C++ function on Solaris? Steve Gilbert Java 3 04-14-2004 04:04 PM
How do we Call an external routine in Perl Bazil Perl Misc 2 12-06-2003 02:20 AM



Advertisments