Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Locked thread
Mithaldu
Sep 25, 2007

Let's cuddle. :3:

Rocko Bonaparte posted:

It doesn't necessarily change what I was trying to say. I know that Pugs was a superhuman effort but Parrot wasn't very complete at the time either. Pugs did allow them to screw around with parts of the language though.

Ok, i guess i expressed that shittily.

Here's what i was trying to say: Your post reads to me like you think there was a deliberate decision by a group of people (committee-style) against Parrot, which never happened as such.

Adbot
ADBOT LOVES YOU

Rocko Bonaparte
Mar 12, 2002

Every day is Friday!

Mithaldu posted:

Ok, i guess i expressed that shittily.

Here's what i was trying to say: Your post reads to me like you think there was a deliberate decision by a group of people (committee-style) against Parrot, which never happened as such.
Ohh no I wasn't trying to imply that at all. Aren't Perl 6 and Parrot consider linked together? It was also presented to me like Parrot was like .NET in that it was a common linkage runtime, with Perl 6 being the C# flagship language to run on it. I can't remember now why people felt like they were blocked on Parrot. This is going back a few years, when I was actually thinking of writing the x86-64 JIT, but the x86 JIT was pretty odd and I was given a perpetual promise/warning that the whole API for that was going to get overhauled anyways. So nothing really came of it. It did seem like Pugs was something like a giant hot air balloon that drifted through the mailing list, with that developer reaching their hand out over the side saying, "Hey guys, hop on!" And then they drifted around on that for awhile.

These days I think I like the idea of Parrot more than Perl 6 itself since Parrot would allow all these languages to work together--so long as people actually convert (dare I say, "compile?") the code to the Parrot asm.

Blotto Skorzany
Nov 7, 2008

He's a PSoC, loose and runnin'
came the whisper from each lip
And he's here to do some business with
the bad ADC on his chip
bad ADC on his chiiiiip
Did this yesterday
code:

-    my $lep = Lingua::EN::Phoneme->new();
+    my $lep;
+    {
+        #read from local dictionary rather than the one L::E::P installs
+        #this way we can write to it to define new words later
+        my $override = Sub::Override->new( 'Lingua::EN::Phoneme::new' =>
+            \&_fake_lep_ctor );
+        $lep = Lingua::EN::Phoneme->new();
+    }
+

...

+sub _fake_lep_ctor {
+    my ($class) = @_;
+    my %self;
+
+    tie %self, 'DB_File', './cmudict.db', O_RDWR, 0644,
+    $DB_File::DB_HASH or die "Can't tie: $!";
+    return bless(\%self, $class);
+}
+

Mithaldu
Sep 25, 2007

Let's cuddle. :3:
That is a pretty neat demonstration of how to use that module.

I also have a question of my own. Two days ago i found myself faced with having a largish codebase that i was tasked with refactoring (really no other goal, because it's entirely poo poo). Since everything in it was bad, i couldn't decide where to begin, so i decided to run some statistics on the code. With a bit of poking at StackOverflow and a lot of reading of PPI documentation i got this script together:

http://gist.github.com/514512

Now I'm thinking about how to convert it into a proper module distro for CPAN, and once again find myself faced with too many ways i can go. As such I'm looking for some input to help me think:

How would you structure this? (i.e. in which different modules)

(I'm intentionally not giving any examples of what I'm thinking of to get 'untainted' reactions.)

SA Support Robot
Apr 20, 2007

Mithaldu posted:

How would you structure this? (i.e. in which different modules)

I'd put the stuff that generates the statistics in its own package and have some interface that returns a stats object. Probably another package to handle outputting stuff in various formats using the stats object. The main script would just process command-line options and glue it all together.

Mithaldu
Sep 25, 2007

Let's cuddle. :3:

SA Support Robot posted:

I'd put the stuff that generates the statistics in its own package and have some interface that returns a stats object. Probably another package to handle outputting stuff in various formats using the stats object. The main script would just process command-line options and glue it all together.

I was hoping for a bit more detail, but i guess i wasn't very detailed either. I've spent the night doing a rough sketch being heavily inspired by the excellent Dist::Zilla of how i think this whole thing can work:

http://github.com/wchristian/code-statistics

Working functionality is like this:

bin/codestat is called as:

codestat collect --dir=/perl/here

It then runs through that directly, finds all files and gets their absolute paths. Then it runs each file against a search that looks for targets that are relevant to statistics. right now only blocks, but it's structured so that it's easy to add in new target types like subs, regexen, etc. Each target has a PPI class i don't think i need to try supporting non-PPI targets, as well as a list of supported metrics. size, length, indentation depth, line number, column number, etc. All found targets are then looped over and the measurements of each supported metric are collected on each target.

That data is then stored in the file object, where it is stripped out back in the main processing module, and then dumped to JSON like so:

code:
[
   {
      "measurements" : {
         "Block" : [
            { "size" : 321 },
            { "size" : 56 }
         ]
      },
      "path" : "C:\\Perl\\lib\\CPANPLUS\\Backend.pm"
   },
   {
      "measurements" : {
         "Block" : [
            { "size" : 314 },
            { "size" : 112 }
         ]
      },
      "path" : "C:\\Perl\\lib\\CPANPLUS\\Shell\\Default\\Plugins\\Source.pm"
   }
]

That can later then be parsed back in and run through various report generation routines. Not particularly concerned with their design right now, but if you know of any modules on CPAN that deal with report generation, I'd be grateful for links.


Now here's what I'm really looking for at this point: The design and structure is extremely bare-bones and only the minimum that i can envision working in the future as well. So, before i start on fleshing it out, i need to see if i can get some cold and brutal criticism. What did i overlook, fail to consider or just plain gently caress up? Where is my design poo poo in ways that will break stuff in the future or make it very hard to change or fix some things?

Also, how do you think of yourself wanting to use this? I already have a bunch of use case scenarios in mind and am planning for the relevant changes, but input from people who aren't me would be invaluable in this department.

My current future plans for the metric collector:
Parameters for:
- directories to search in (. as default)
- file extensions to look for (File::Find::Rule::Perl as default)
- file ignore patterns (empty as default)
- custom lists of target ppi objects (planning to have it use only block as default)
- custom metric lists (planning to have it use all by default)
- config files looked for in current directory as well as in user directory
- config files containing a global profile, as well as specific profiles, which can be used to generate parameter sets with this precendence: userdir( global < specific ) < cwd( global < specific ) < command line

Mithaldu
Sep 25, 2007

Let's cuddle. :3:
A small side result of my wrestling with the code statistics thing:

Test::Class::TestGroup

Rohaq
Aug 11, 2006
Has anyone got any tips on working with large files in Perl? I want to work on encrypting files, but I foresee problems with encrypting larger files, both binary and ASCII, as they would likely need to be loaded into memory before any operation can be performed on them.

I'm Googling in the meantime, but it anyone has any suggestions, I'm all ears.

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe
Perl isn't going to force you to read the whole file into memory at once, and if you can possibly avoid doing so, you should. You probably don't need random access to the entire file; maybe you can collect the information you need in a first pass, then encrypt the file in a second? This is language-agnostic advice.

Rapportus
Oct 31, 2004
The 4th Blue Man

Rohaq posted:

Has anyone got any tips on working with large files in Perl? I want to work on encrypting files, but I foresee problems with encrypting larger files, both binary and ASCII, as they would likely need to be loaded into memory before any operation can be performed on them.

I'm Googling in the meantime, but it anyone has any suggestions, I'm all ears.

I've always used Tie::File for processing large files.

octobernight
Nov 25, 2004
High Priest of the Christian-Atheist Church
I've build a helper.pm full of helpful functions. I'm now working on an interactive command line that allows me to easily call functions from helper.pm. However, I'm having problems getting the syntax down.

For example, if I have a defined function test which prints "Hello world", then the following would call that function:

my $function = "test"
&{$function}();

However, if I have a defined function test in helper.pm, I don't know how to call it from another file. All the following fail:

&{Helper::$function}();
&Helper::{$function}();
Helper::&{$function}();
$Helper::&{$function}();

Does anyone know the solution to this problem? Thanks!

Mario Incandenza
Aug 24, 2000

Tell me, small fry, have you ever heard of the golden Triumph Forks?
Well, calling functions indirectly and tightly coupled like that is kinda asking for trouble, but here's how to do it (even when using strict):

code:
sub foo { 'foo' }

my $method_name = 'foo';
my $ref = \&{ $method_name };

warn $ref->();
But you should really be using a dispatch table, or consider swapping to an OO-based system with proper reflection, instead of resorting to nasty hacks or manually defined mappings.

octobernight
Nov 25, 2004
High Priest of the Christian-Atheist Church

Mario Incandenza posted:

Well, calling functions indirectly and tightly coupled like that is kinda asking for trouble, but here's how to do it (even when using strict):

code:
sub foo { 'foo' }

my $method_name = 'foo';
my $ref = \&{ $method_name };

warn $ref->();
But you should really be using a dispatch table, or consider swapping to an OO-based system with proper reflection, instead of resorting to nasty hacks or manually defined mappings.

Yeah, this isn't the best solution. I am using this for testing my in house development tools and haven't had time to come up with a more elegant method due to other pressing issues. My main problem was my subroutines are in a different file, so I'm not sure how to call those functions. I was unclear about the syntax to make the call. However, I've figured it out.

code:
package foo
sub test {
  print "Hello\n";
}
1;
code:
use foo

my $method_name = 'test';
my $class_name = 'foo';
#Call test in foo.pm?
$class_name->$method_name();
Thanks for the reply!

toadee
Aug 16, 2003

North American Turtle Boy Love Association

You can also do something like this:

in foo.pm:
code:
sub new {
    my $class = shift;
    my $self = {};
    bless( $self, $class );
    return $self;
}

... write other subs and such ...
Then in your other programs use:

code:
use foo;

my $bar = foo->new();
$bar->test();

toadee fucked around with this message at 13:36 on Sep 29, 2010

Kynetx
Jan 8, 2003


Full of ignorant tribalism. Kinda sad.
I intend to build a text-driven app that will allow lay-people to work their way down a decision tree where each step combines modular blocks of pre-written text and inserts variables to generate configuration files. Basically something like this:
code:
Widget configurator version .90

Select your widget
1.Widget Systems Doohickey 1000
2.Widget Systems Doohickey 1500
3.Widget Systems Doohickey 2000
A user selects option 2 and the text-file building begins. The script will go and grab the block of text corresponding to option 2 and write it to the file. Then:

code:
Widget configurator version .90

Select slot 1 plug-in module
1.Fleegman module
2.Pseudo-Fleegman module with Fetzer Valve
3.Skyhook telemety module
The user selects option 1, the script writes the corresponding block of text to the file and goes to the next object, etc.

This is a fairly simplistic example and the finished product will be able to parse text to detect error messages, be able to use FTP for file transfer, be made to wait for x number of seconds, etc. What I want to do seems beyond batch files or Aspect scripting. Does this look like a good application for Perl? I have practically no experience with code, but I can learn, dammit.

Erasmus Darwin
Mar 6, 2001

Kynetx posted:

Does this look like a good application for Perl?

Everything you mentioned sounds relatively easy in Perl. For the FTP transfer part, Perl's got the Net::FTP module in CPAN.

Blotto Skorzany
Nov 7, 2008

He's a PSoC, loose and runnin'
came the whisper from each lip
And he's here to do some business with
the bad ADC on his chip
bad ADC on his chiiiiip
Wanted to submit a patch to fix WWW::google::Calculator yesterday, so I finally got off my arse and got my PAUSE id set up. The id didn't get recognized by rt.cpan.org immediately, so I submitted the bug report and patch via email and gitpan instead :downsgun:

Mithaldu
Sep 25, 2007

Let's cuddle. :3:

Otto Skorzeny posted:

Wanted to submit a patch to fix WWW::google::Calculator yesterday, so I finally got off my arse and got my PAUSE id set up. The id didn't get recognized by rt.cpan.org immediately, so I submitted the bug report and patch via email and gitpan instead :downsgun:

Depending on which author you're dealing with, github might even be the better choice to push out patches. I know i've gotten picked up more by just forking things and hacking on them.

Blotto Skorzany
Nov 7, 2008

He's a PSoC, loose and runnin'
came the whisper from each lip
And he's here to do some business with
the bad ADC on his chip
bad ADC on his chiiiiip
Yeah, the fork & pull request model seems pretty convenient

Super Delegate
Jan 20, 2005

ƃɐlɟ ǝɥʇ
I have an array that I'm trying to output into a table. I want to alternate outputting text in first and second columns. Right now I'm able to send the correct data to one column, but I don't know how to do so for both columns.

code:
@datapart = grep{!($n++ % 2)} @data;
@otherdatapart = grep{($n++ % 2)} @data;



print '<table width="250" border="2">';
foreach $item1(@datapart)
{
 print "<tr><td>$item1</td><td>$otheritem(doesnt work)</td></tr>\n\n";
}
print '</table>';
Edit: Thanks Erasmus Darwin, the code worked perfectly.

Super Delegate fucked around with this message at 06:37 on Nov 6, 2010

Erasmus Darwin
Mar 6, 2001
code:
@temp_data = @data;

print '<table width="250" border="2">';
while (@temp_data) {
  $item1 = shift(@temp_data);
  $otheritem = shift(@temp_data) || '';
  print "<tr><td>$item1</td><td>$otheritem</td></tr>\n\n";
}
print '</table>';

Nevergirls
Jul 4, 2004

It's not right living this way, not letting others know what's true and what's false.
Your two-column table looks suspiciously like a hash:
code:
my %data = @data;

print '<table width="250" border="2">';
for my $k (sort keys %data) {
  print "<tr><td>$k</td><td>$data{$k}</td></tr>\n";
}
print '</table>';

Triple Tech
Jul 28, 2006

So what, are you quitting to join Homo Explosion?
Keep in mind the above/latest/hash technique won't work if the keys are not unique.

Dooey
Jun 30, 2009
I have a 3d hash, and I am populating it by building 2d hashes using a function that returns references to 2d hashes and I want to merge the "inner" 3d hash with the 2d hash. If they were both 2d hashes I would do this:

code:
my %hash2d_A;
my $hash2d_B_ref = foo();
%hash2d_A = ($hash2d_A, %$hash2d_B_ref);
But when I try something similar with a 3d hash and a 2d hash it doesn't work

code:
my %hash3d;
my $hash2d_ref = foo();
my $some_key = "a string";
$hash3d{$some_key} = ($hash3d{$some_key}, %$hash2d_ref);
What should I be doing?

Mithaldu
Sep 25, 2007

Let's cuddle. :3:

Dooey posted:

What should I be doing?

You need to do with hash4d the same thing you did with hash2d: Dereference it. You also need to wrap the whole thing in curlies to make it generate an anonymous hash. Like so:

code:
$hash3d{$some_key} = { %{$hash3d{$some_key}}, %$hash2d_ref };
Basically: Curl the gently caress out of it.

Paradox
May 19, 2003

Super Delegate posted:

I have an array that I'm trying to output into a table. I want to alternate outputting text in first and second columns. Right now I'm able to send the correct data to one column, but I don't know how to do so for both columns.

code:
@datapart = grep{!($n++ % 2)} @data;
@otherdatapart = grep{($n++ % 2)} @data;



print '<table width="250" border="2">';
foreach $item1(@datapart)
{
 print "<tr><td>$item1</td><td>$otheritem(doesnt work)</td></tr>\n\n";
}
print '</table>';

Another way is that if have the List::MoreUtils module or can get it from CPAN then you can use the natatime function.

code:
use List::MoreUtils qw(natatime);
@datapart = grep{!($n++ % 2)} @data;
@otherdatapart = grep{($n++ % 2)} @data;

print '<table width="250" border="2">';
my $it = natatime 2, @datapart;
while (my @items = $it->()) {
  print "<tr><td>$items[0]</td><td>$items[1]</td></tr>\n\n";
}
http://search.cpan.org/~vparseval/List-MoreUtils-0.22/lib/List/MoreUtils.pm

Filburt Shellbach
Nov 6, 2007

Apni tackat say tujay aaj mitta juu gaa!

Otto Skorzeny posted:

The id didn't get recognized by rt.cpan.org immediately]

rt.cpan only syncs new accounts a couple times (maybe only once?) a day

qntm
Jun 17, 2009
code:
print("K");
while(1) {
  sleep(1);
}
Why doesn't this print the letter "K"?

baquerd
Jul 2, 2007

by FactsAreUseless

qntm posted:

code:
print("K");
while(1) {
  sleep(1);
}
Why doesn't this print the letter "K"?

Buffers.

Try $| = 1;

tef
May 30, 2004

-> some l-system crap ->

qntm posted:

Why doesn't this print the letter "K"?

Standard out is line buffered. Either terminate strings with \n, or flush the buffer:

The $| variable sets 'autoflush' in perl

Warthog
Mar 8, 2004
Ferkelwämser extraordinaire
I've got a list of family names I'd like to sort by their ending... I thought reversing them all would be the easiest way so I wrote this tiny thingy:
code:
while (<>) {
 $reversed = reverse($_);
 print $reversed;
}
so far so good - the only problem is that the list looks like this:
Аалунд
Абабков
Абаджев
...
and perl doesn't seem to like reversing utf-8 at all :(
edit: trying to find out how to use this String::Multibyte thing - maybe that's the solution

I'm stupid - here's the solution:

code:
use utf8;
use open IN => ':utf8';
binmode STDOUT, 'utf8';
while (<>) {
 $reversed = scalar reverse($_);
 print $reversed;
}

Warthog fucked around with this message at 01:15 on Nov 4, 2010

Mithaldu
Sep 25, 2007

Let's cuddle. :3:
Right now at work we have a 400mb moloch of an SVN repo and i'm wanting hard to get that moved to git and eventually split up. The CTO gave me the go-ahead to write an email as to why git, and how to do it.

Can you guys link me to recent write-ups on the advantages of git over svn that are more amenable to a management-type target audience?

Cuddles
Jan 9, 2003

Be Afraid
Here's one that has me pounding my head against a wall. I have an Apache VirtualHost that is served by two machines behind a load-balancer. I need to accurately get the load time from server A vs server B for a specific URL that resolves to the load balancer. I'm trying to find some way to make a "hostfile" that's local to the script itself without affecting name resolution for the rest of the monitoring server. There are 20,000 different ways to access the standard gethostbyname() function, but I have to find a way to short-circuit it. Thoughts? Ideas? Comments? Offers of alcohol?

Erasmus Darwin
Mar 6, 2001

Cuddles posted:

I need to accurately get the load time from server A vs server B for a specific URL that resolves to the load balancer.

Instead of going crazy by subverting DNS, I'd suggest just hitting the IP of server A or server B directly with the Host header set to the appropriate VirtualHost.

code:
use LWP::UserAgent;

my $ua = LWP::UserAgent->new;

my $req = HTTP::Request->new(GET => 'http://10.0.5.10/load_speed_test'); # Server A's hypothetical IP
$req->header(Host => 'www.example.com');

my $res = $ua->request($req);

if ($res->is_success) {
  print $res->content;
}

Cuddles
Jan 9, 2003

Be Afraid

Erasmus Darwin posted:

Instead of going crazy by subverting DNS, I'd suggest just hitting the IP of server A or server B directly with the Host header set to the appropriate VirtualHost.

code:
use LWP::UserAgent;

my $ua = LWP::UserAgent->new;

my $req = HTTP::Request->new(GET => 'http://10.0.5.10/load_speed_test'); # Server A's hypothetical IP
$req->header(Host => 'www.example.com');

my $res = $ua->request($req);

if ($res->is_success) {
  print $res->content;
}

You are a scholar and a gentleman. I've been so busy hammering on name resolution I completely ignored the LWP headers.

Mario Incandenza
Aug 24, 2000

Tell me, small fry, have you ever heard of the golden Triumph Forks?
Just read about 5.13.7's keys(), push(), pop() etc now accepting refs as valid containers, noice. That was one of the few things that still seems to bug me about Perl's syntax.

e.g. say() foreach keys $obj->returns_hashref()

Blotto Skorzany
Nov 7, 2008

He's a PSoC, loose and runnin'
came the whisper from each lip
And he's here to do some business with
the bad ADC on his chip
bad ADC on his chiiiiip
I didn't even know the delta for 5.13.7 was out yet :shobon:

syphon
Jan 1, 2001
I've been bashing my head against this problem, and I suspect I'm starting to see it sideways. Can someone help me access this complex data structure?

Basically, I'm taking an XML page of hardware info and using XML::Simple's XMLIn() function to put into a Perl data structure. Now I'm trying to parse that data and show meaningful information to the user.

Here is a snippet of that data - the output of running 'print Dumper(@Processors);' to be exact:
code:
$VAR1 = [
          {
            'CLOCKSPEED' => '2400 MHz',
            'EXTERNALCLOCK' => ' MHz',
            'PROCESSORTYPE' => 'Central Processor',
            'LEVEL' => '15',
            'ARCHITECTURE' => 'x64',
            'L2CacheSpeed' => ' MHz',
            'NAME' => 'Dual-Core AMD Opteron(tm) Processor 2216 HE',
            'STEPPING' => '3',
            'SOCKETDESIGNATION' => 'Proc 1',
            'L2CacheSize' => '2MB',
            'REVISION' => '16643',
            'DATAWIDTH' => '64',
            'ADDRESSWIDTH' => '64',
            'DEVICEID' => 'CPU0',
            'MAXCLOCKSPEED' => '2400 MHz',
            'DESCRIPTION' => 'AMD64 Family 15 Model 65 Stepping 3',
            'MANUFACTURER' => 'AuthenticAMD',
            'VERSION' => 'Model 1, Stepping 3',
            'AVAILABILITY' => 'Full Power',
            'FAMILY' => "AMD Athlon\x{2122} 64 Processor Famiily"
          },
          {
            'CLOCKSPEED' => '2400 MHz',
            'EXTERNALCLOCK' => ' MHz',
            'PROCESSORTYPE' => 'Central Processor',
            'LEVEL' => '15',
            'ARCHITECTURE' => 'x64',
            'L2CacheSpeed' => ' MHz',
            'NAME' => 'Dual-Core AMD Opteron(tm) Processor 2216 HE',
            'STEPPING' => '3',
            'SOCKETDESIGNATION' => 'Proc 2',
            'L2CacheSize' => '2MB',
            'REVISION' => '16643',
            'DATAWIDTH' => '64',
            'ADDRESSWIDTH' => '64',
            'DEVICEID' => 'CPU1',
            'MAXCLOCKSPEED' => '2400 MHz',
            'DESCRIPTION' => 'AMD64 Family 15 Model 65 Stepping 3',
            'MANUFACTURER' => 'AuthenticAMD',
            'VERSION' => 'Model 1, Stepping 3',
            'AVAILABILITY' => 'Full Power',
            'FAMILY' => "AMD Athlon\x{2122} 64 Processor Famiily"
          }
        ];
Unless I'm mistaken. that's an anonymous array of anonymous hashes, right? How the hell do I access that data? Evaluating "ref(@Processors)" returns nothing, so it's a pure array, not a reference to anything. However, when running "print $#Processors" (to see how many elements are in the array) it returns a 0. Trying to loop over the array with "for (@Processors) { ... }" executes no code either.

So, I guess that means it's not a reference to anything, but it's also not an array? Am I being very stupid here?

syphon fucked around with this message at 01:03 on Dec 8, 2010

The Gate of Nanna
Sep 20, 2008

:c00l: My Editor :c00l:

syphon posted:

How the hell do I access that data?

print $array->[0]->{CLOCKSPEED};

gets you '2400 MHz'.

With references you have to dereference to get the values. So for (@{$Processors} { ... } is how you tell perl to turn it back into array from a scalar.

syphon posted:

Am I being very stupid here?

Not at all. Perl can be weird depending on what background you come from. If it's C, then it makes more sense.

Adbot
ADBOT LOVES YOU

syphon
Jan 1, 2001

The Gate of Nanna posted:

print $array->[0]->{CLOCKSPEED};

gets you '2400 MHz'.

With references you have to dereference to get the values. So for (@{$Processors} { ... } is how you tell perl to turn it back into array from a scalar.
Ok, so how do I loop over each array element and access that data? Running "print $array->[0]->{CLOCKSPEED};" does indeed output '2400 MHz', but running
code:
for (@{$Processors}) 
  { 
    print $Processors->[$_]->{CLOCKSPEED}; 
  }
outputs an infinite loop of "2400 MHz", even though the array only has 2 elements.

  • Locked thread