Thursday, July 30, 2009

Ambigous Win32:OLE::LastError() Message

Running this code snippet:
use Win32::OLE;
$lrEngine = Win32::OLE->new('wlrun.LrEngine');
$lrScenario = $lrEngine->Scenario();
$rc = $lrScenario->new(0, 1);
# do not save previous
# regular vusers based scenario

$scriptLocation = 'PATH\TO\SCRIPTNAME\SCRIPTNAME.usr';
$scriptName = 'SCRIPTNAME';
$lrScenario->Scripts->Add($scriptLocation, $scriptName);
print "Win32::OLE::LastError: ".Win32::OLE::LastError()."\n";
Yields:
Win32::OLE::LastError: Win32::OLE(0.1709) error 0x80020005: "Type mismatch"
in METHOD/PROPERTYGET "Add" argument 2
Yes, the code passes string, even changing the code to force COM BSTR usage still generates the same error message
use Win32::OLE::Variant;
$scriptName = Variant(VT_BSTR, 'SCRIPTNAME');
What gives? The code definitely follows the documentation to the dot
Function Add(Path As String, Name As String) As Long
Add Script to Scenario
The answer: Variants by reference, changing the code, to reflect the snippet below, fixes the problem.
use Win32::OLE::Variant;
$scriptName = Variant(VT_BSTR|VT_BYREF, 'SCRIPTNAME');

Wednesday, July 29, 2009

Submitted 1st Perl Bug To ActiveState

http://bugs.activestate.com/show_bug.cgi?id=83895

--Note: I see, basically reverse doesn't sort the list in reverse order, but it will reverse the list.

Reverse Function Is Not Working Properly

Dan caught it, not me
use strict;
my $DATA;
{
local $/ = undef;
my $DATA_text = ;
eval "$DATA_text";
die $@ if $@;
}
print "# incorrect reverse sort using reverse function\n";
foreach my $date (reverse keys %{$DATA}) {
print "$date\n";
}
print "\n";
print "# correct reverse sort\n";
foreach my $date (sort {$b cmp $a} keys %{$DATA}) {
print "$date\n";
}

__DATA__
$DATA = {
'2009/07/19' => {
files => 1,
},
'2009/07/12' => {
files => 1,
},
'2009/07/05' => {
files => 1,
},
'2009/06/28' => {
files => 1,
},
'2009/06/21' => {
files => 1,
},
};

It prints:
>perl reverse_problem.pl
# incorrect reverse sort using reverse function
2009/07/12
2009/07/05
2009/07/19
2009/06/28
2009/06/21

# correct reverse sort
2009/07/19
2009/07/12
2009/07/05
2009/06/28
2009/06/21

>perl -v

This is perl, v5.8.8 built for MSWin32-x86-multi-thread
(with 18 registered patches, see perl -V for more detail)

Copyright 1987-2007, Larry Wall

Binary build 822 [280952] provided by ActiveState http://www.ActiveState.com
Built Jul 31 2007 19:34:48

Perl may be copied only under the terms of either the Artistic License or the
GNU General Public License, which may be found in the Perl 5 source kit.

Complete documentation for Perl, including FAQ lists, should be found on
this system using "man perl" or "perldoc perl". If you have access to the
Internet, point your browser at http://www.perl.org/, the Perl Home Page.

--Apparently I can reproduced this using ActiveState v5.10.0 build 1001 [283495]

Monday, June 15, 2009

Collect My Passport

The window opens from 13:30 to 16:00. I arrived 15:55. I hate LA's traffic.

Thursday, June 11, 2009

Ambiguous Extraction

Say you need to extract the id of Company A as originator ({pOriginatorName}) and Company A as underwriter ({pUnderwriterName}), what should you do when you encounter this response?

<html>
<head />
<body>
...
<select name="originator">
<option selected value="0">Company A</value>
<option value="1">Company B</value>
<option value="2">Company C</value>
</select>
...
<select name="underwriter">
<option value="-1">Please select</value>
<option value="9005">Company A</value>
<option value="9006">Company B</value>
</select>
...
</body>
</html>
Then it's time to use the XML functions provided by the good people of Mercury (now HP), first extract the options inside the select element by using web_reg_save_param function:
web_reg_save_param("pOriginatorIDText",
"LB/IC=name=\"originator\"",
"RB/IC=</select>",
"Ord=1",
"Search=body",
LAST);

web_reg_save_param("pUnderwriterIDText",
"LB/IC=name=\"underwriter\"",
"RB/IC=</select>",
"Ord=1",
"Search=body",
LAST);


Follow by the functions to extract the related values:
iNumOfValues = lr_xml_get_values("XML=<select {pOriginatorIDText}</select>",
"ValueParam=pCollectedOriginatorName",
"Query=/select/option",
"SelectAll=yes",
LAST);

iNumOfValues = lr_xml_get_values("XML=<select {pOriginatorIDText}</select>",
"ValueParam=pCollectedOriginatorID",
"Query=/select/option/@value",
"SelectAll=yes",
LAST);

for (i = 0; i < iNumOfValues; i++) {
sprintf(buf, "{pCollectedOriginatorName_%d}", i+1);
sprintf(buf, rtrim(lr_eval_string(buf)) );
sprintf(sParamName, "pCollectedOriginatorName_%d", i+1);
lr_save_string(buf, sParamName);

if (strcmp(buf, lr_eval_string("{pOriginatorName}")) == 0) {
lr_output_message("Originator name found");
sprintf (buf, "{pCollectedOriginatorID_%d}", i+1);
lr_save_string(lr_eval_string(buf), "pOriginatorID");
}

sprintf (buf, "Retrieved value %d : {pCollectedOriginatorName_%d}", i+1, i+1);
lr_output_message(lr_eval_string(buf));
}
//#####################################
iNumOfValues = lr_xml_get_values("XML=<select {pUnderwriterIDText}</select>",
"ValueParam=pCollectedUnderwriterName",
"Query=/select/option",
"SelectAll=yes",
LAST);

iNumOfValues = lr_xml_get_values("XML=<select {pUnderwriterIDText}</select>",
"ValueParam=pCollectedUnderwriterID",
"Query=/select/option/@value",
"SelectAll=yes",
LAST);

for (i = 0; i < iNumOfValues; i++) {
sprintf(buf, "{pCollectedUnderwriterName_%d}", i+1);
sprintf(buf, rtrim(lr_eval_string(buf)) );
sprintf(sParamName, "pCollectedUnderwriterName_%d", i+1);
lr_save_string(buf, sParamName);

if (strcmp(buf, lr_eval_string("{pUnderwriterName}")) == 0) {
lr_output_message("Underwriter name found");
sprintf (buf, "{pCollectedUnderwriterID_%d}", i+1);
lr_save_string(lr_eval_string(buf), "pUnderwriterID");
}

sprintf (buf, "Retrieved value %d : {pCollectedUnderwriterName_%d}", i+1, i+1);
lr_output_message(lr_eval_string(buf));
}

Yes, it looks complicated, but:
pOriginatorID = 0
pUnderwriterID = 9005

Mish Mash Of Different Version Work

This is weird, but LR controller v9.1 can talk & run scripts when paired with generator v7.8FP1, vice versa.

Test it this morning.

Wednesday, June 10, 2009

rtrim

Delete trailing spaces
char *rtrim(char * string)
{
while (strcmp(strrchr(string, ' '), " ") == 0) {
string[strlen(string)-1] = 0;
}
return string;
}
Googled this and can't find good solution.

Wednesday, June 3, 2009

Use PPM-Make To Make My Own PPM Repository

After getting tired of disappearing modules @ theoryx5.uwinnipeg.ca, and having to merge the files between several machines manually, I decided to build my own repository.

Luckily, Randy Kobes (the maintainer of theoryx5.uwinnipeg.ca) also releases PPM-Make to compile the code from scratch, together with the release of MinGW under PPM, these make my life a lot easier to compile and host the ppm myself.

Playing with the PPM-Make module for a while, I realized that I sorely need:
  1. To organize the directory structure
    • The .ppd & .tar.gz files: http://angrybots.com/ppm/as_p5_8_b822/x86/sandbox/
    • Archive (zip file for local install): http://angrybots.com/ppm/as_p5_8_b822/x86/sandbox/zips/
  2. Another option (I named it vsz) to insert the version of the module to the zip file name for archiving purposes.
After hacking and gluing everything together, I present Acme-Bleach from my repository. To install:
> ppm install http://angrybots.com/ppm/as_p5_8_b822/x86/sandbox/Acme-Bleach.ppd

I'll upload more modules as I get them successfully compiled and tested.

Tuesday, June 2, 2009

PPM-Make

Just research the PPM::Make problem on my desktop, it appears that it has v0.94, I need to upgrade it to v0.96, and that's not half of the problem: apparently the ppm repository at theoryx5.uwinnipeg.ca doesn't have v0.96. Surprise!

So I need to add tcool.org PPM repository:
> ppm repo add http://ppm.tcool.org/archives/package.xml

Researching the module again:
>ppm search ppm-make
1: PPM-Make
Make a ppm package from a CPAN distribution
Version: 0.940
Repo: theoryx5.uwinnipeg.ca

2: PPM-Make
Make a ppm package from a CPAN distribution
Version: 0.96
Repo: ppm.tcool.org

Remedy:
>ppm install 2 --force
Downloading PPM-Make-0.96...done
Downloading libwww-perl-5.826...done
Downloading version-0.76...done
Downloading IO-Compress-2.019...done
Downloading Compress-Raw-Bzip2-2.019...done
Downloading Compress-Raw-Zlib-2.019...done
Unpacking PPM-Make-0.96...done
Unpacking libwww-perl-5.826...done
Unpacking version-0.76...done
Unpacking IO-Compress-2.019...done
Unpacking Compress-Raw-Bzip2-2.019...done
Unpacking Compress-Raw-Zlib-2.019...done
Generating HTML for PPM-Make-0.96...done
Generating HTML for libwww-perl-5.826...done
Generating HTML for version-0.76...done
Generating HTML for IO-Compress-2.019...done
Generating HTML for Compress-Raw-Bzip2-2.019...done
Generating HTML for Compress-Raw-Zlib-2.019...done
Updating files in site area...done
169 files installed
8 files unchanged
22 files updated

Last, for $ENV{PATH} move C:\Perl5.8.8\site\bin to the front of C:\Perl5.8.8\bin

Friday, May 29, 2009

PPM-Make Is Goodz

Last night, I half jokingly installed PPM::Make and MinGW for Perl 5.8.8 on the laptop and built ORM 0.95. It worked. What was going on with my desktop?

Thursday, May 28, 2009

ATM Eats Ma Check!

Oh, how I hate these old ATM that eat checks in envelope

The Hole Feels Like Home Now

After AT&T opens the tap, now go back to hacking the power outlets/cabling ...

Tuesday, May 26, 2009

Leeching Moment - Last Day

Arrived at the hole 2AM in the morning after driving all the way from LA only to find non-working internet. Re-register the modem, no luck. Reboot modem - wait - no packet. Re-register the modem again, no internet. Tired, I decided to go to sleep.

Wake up 6:30AM hoping the people in St Louis have fixed it since they have a head start. No luck, no internet. Call the AT&T Broadband Customer Care, someone run basic test again and tell me to call back in 2 hours since he just files a ticket.

Why new ticket? The little voice in my head query - no time to think, time to work. Suckling the wifi at Starbucks at 7:30AM.

Around 10, I decided that I had enough fiddling with the script, decided to go home and follow up with AT&T. To my dismay, the pipe wasn't working and someone named Renee from AT&T had to hear me screaming like a mad man about their stupid bot closing the previous ticket and demanded her to follow up personally since today is the 6th day of their nonoperational service.

Miraculously, the internet starts working around 11:30 - yay!

Btw, I borrowed Mr Smith Goes to Washington, Gattaca, The Fountain and The Painted Veil from Sunnyvale Public Library.

Monday, May 25, 2009

Memorial Day

First thing first - sleep - but the AT&T bot woke up me up, I hit the red button and resumed sleeping until Stanley was about to leave, helped him with the luggage.

Caught some sleep - but I had to break for lunch.

Napping again, I need to be on top of my game tonight since we are to leave LA late, forced myself to wake up around 16:30 and drive to Simi Valley.

Had BBQ dinner and we leave for Bay Area at 20:00.

Sunday, May 24, 2009

Stella's Wedding

Spend the morning sleeping - break for lunch - and back to spend the whole afternoon with myself, enjoying coffee with Top Gear.

Get out of the house around 3:30, pick up the family and arrive at the Muckenthaler Cultural Center at 5PM sharp.

Ceremony starts around 17:15, tea ceremony, photo ops and reception afterward.

The party ends at 10PM, I help with shuttling the gifts and we hang out at the hotel with the family members until 1AM in the morning. Bone tired ... but happy.