Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Looking for a way to enhance the implementation 2

Status
Not open for further replies.

whn

Programmer
Oct 14, 2007
265
US
I have a piece of codes constructing an email sender:

Code:
sub getSender {
  my $host = hostname;a # use Sys::Hostname;
  my $domain = 'xyz.com';
  my $char = '.';
  my $from;
  if($host =~ /$domain/) {
    # hostname() may return a string like foo.bar.xyz.com and in this case
    # we want to return foo@bar.xyz.com [COLOR=blue]
    my $ind = index($host, $char);
    my $p1 = substr($host, 0, $ind);
    my $p2 = substr($host, $ind+1);
    $from = $p1.'@'.$p2;[/color]
  }
  else {
    # hostname() simply returns 'foo'
    $from = $host.'@'.$domain;
  }
  return $from;
}

The blue section does not look pretty to me. Is there a way to enhance it using one-liner?

Many thanks.
 
Hi

Like this ?
Perl:
[b]while[/b] [teal]([/teal][b]chomp[/b][teal]([/teal][navy]$data[/navy] [teal]=[/teal] [i][green]<DATA>[/green][/i][teal])) {[/teal]
  [b]printf[/b] [i][green]"%-15s | %-20s | %s\n"[/green][/i][teal],[/teal] [navy]$data[/navy][teal], &[/teal][COLOR=orange]getSender[/color][teal](), &[/teal][COLOR=orange]getSender2[/color][teal]();[/teal]
[teal]}[/teal]

[b]sub[/b] hostname [teal]{[/teal] [navy]$data[/navy] [teal]}[/teal]

[b]sub[/b] getSender [teal]{[/teal]
  [b]my[/b] [navy]$host[/navy] [teal]=[/teal] hostname[teal];[/teal] [gray]# use Sys::Hostname;[/gray]
  [b]my[/b] [navy]$domain[/navy] [teal]=[/teal] [i][green]'xyz.com'[/green][/i][teal];[/teal]
  [b]my[/b] [navy]$char[/navy] [teal]=[/teal] [i][green]'.'[/green][/i][teal];[/teal]
  [b]my[/b] [navy]$from[/navy][teal];[/teal]
  [b]if[/b][teal]([/teal][navy]$host[/navy] [teal]=~[/teal] [i][green]/$domain/[/green][/i][teal]) {[/teal]
    [gray]# hostname() may return a string like foo.bar.xyz.com and in this case[/gray]
    [gray]# we want to return foo@bar.xyz.com [/gray]
    [b]my[/b] [navy]$ind[/navy] [teal]=[/teal] [b]index[/b][teal]([/teal][navy]$host[/navy][teal],[/teal] [navy]$char[/navy][teal]);[/teal]
    [b]my[/b] [navy]$p1[/navy] [teal]=[/teal] [b]substr[/b][teal]([/teal][navy]$host[/navy][teal],[/teal] [purple]0[/purple][teal],[/teal] [navy]$ind[/navy][teal]);[/teal]
    [b]my[/b] [navy]$p2[/navy] [teal]=[/teal] [b]substr[/b][teal]([/teal][navy]$host[/navy][teal],[/teal] [navy]$ind[/navy][teal]+[/teal][purple]1[/purple][teal]);[/teal]
    [navy]$from[/navy] [teal]=[/teal] [navy]$p1[/navy][teal].[/teal][i][green]'@'[/green][/i][teal].[/teal][navy]$p2[/navy][teal];[/teal]
  [teal]}[/teal]
  [b]else[/b] [teal]{[/teal]
    [gray]# hostname() simply returns 'foo'[/gray]
    [navy]$from[/navy] [teal]=[/teal] [navy]$host[/navy][teal].[/teal][i][green]'@'[/green][/i][teal].[/teal][navy]$domain[/navy][teal];[/teal]
  [teal]}[/teal]
  [b]return[/b] [navy]$from[/navy][teal];[/teal]
[teal]}[/teal]

[b]sub[/b] getSender2 [teal]{[/teal]
  [b]my[/b] [navy]$host[/navy] [teal]=[/teal] hostname[teal];[/teal] [gray]# use Sys::Hostname;[/gray]
  [b]my[/b] [navy]$domain[/navy] [teal]=[/teal] [i][green]'xyz.com'[/green][/i][teal];[/teal]
  [b]my[/b] [navy]$char[/navy] [teal]=[/teal] [i][green]'.'[/green][/i][teal];[/teal]
  [b]my[/b] [navy]$from[/navy] [teal]=[/teal] [navy]$host[/navy] [teal]=~[/teal] [i][green]/\Q$char\E(.*\Q$domain\E)$/[/green][/i] [teal]?[/teal] [i][green]"$`\@$1"[/green][/i] [teal]:[/teal] [i][green]"$host\@$domain"[/green][/i][teal];[/teal]
  [b]return[/b] [navy]$from[/navy][teal];[/teal]
[teal]}[/teal]

__DATA__
foo[teal].[/teal]bar[teal].[/teal]xyz[teal].[/teal]com
foo
xyzwcom
abcxyzwcom
xyzwcomabc
Code:
foo.bar.xyz.com | foo@bar.xyz.com      | foo@bar.xyz.com
foo             | foo@xyz.com          | foo@xyz.com
xyzwcom         | xyzwco@xyzwcom       | xyzwcom@xyz.com
abcxyzwcom      | abcxyzwco@abcxyzwcom | abcxyzwcom@xyz.com
xyzwcomabc      | xyzwcomab@xyzwcomabc | xyzwcomabc@xyz.com

Feherke.
feherke.ga
 
I love it. Thank you, Feherke!
 
Hi, Feherke,

I have a follow-up question.

Some people like one-liner because it's sophisticated. Some people hate it because it's hard to read and sometimes less efficient (e.g. one-liner to check a prime number). In the case above, getSender() vs. getSender2(), what's your opinion? Which way do you like better and why?

Many thanks!

@feherke
 
Hi

Well, I started coding on XT with 640 Kb RAM and 80x25 text mode display. These 2 are already enough to prefer compact code.

If that was not enough slow, I had the opportunity to code abit on Enterprise too, where the slowness of IS-Basic ( although is still the strongest Basic I ever met ) really put you on thinking.

For example have you played coding something interactive where you moved a cursor with [kbd]↑[/kbd](72)/[kbd]↓[/kbd](80)/[kbd]←[/kbd](75)/[kbd]→[/kbd](77) keys ( in parenthesis their scan codes ) ?

Well, usually such thing is implemented with 2 scalar variables for the 2 coordinats and a switch statement to decide which coordinate needs to be changed :
Perl:
[b]use[/b] [purple]5.10[/purple][teal].[/teal][purple]1[/purple][teal];[/teal]
[b]no[/b] warnings [i][green]'experimental'[/green][/i][teal];[/teal]

[navy]$x[/navy] [teal]=[/teal] [purple]10[/purple][teal];[/teal]
[navy]$y[/navy] [teal]=[/teal] [purple]10[/purple][teal];[/teal]
[b]foreach[/b] [navy]$key[/navy] [teal]([/teal][purple]72[/purple][teal],[/teal] [purple]80[/purple][teal],[/teal] [purple]75[/purple][teal],[/teal] [purple]77[/purple][teal],[/teal] [purple]80[/purple][teal],[/teal] [purple]77[/purple][teal],[/teal] [purple]80[/purple][teal],[/teal] [purple]77[/purple][teal],[/teal] [purple]80[/purple][teal]) {[/teal]
    [COLOR=orange]given[/color] [teal]([/teal][navy]$key[/navy][teal]) {[/teal]
        [COLOR=orange]when[/color][teal]([/teal][purple]72[/purple][teal]) {[/teal] [navy]$y[/navy][teal]-- }[/teal]
        [COLOR=orange]when[/color][teal]([/teal][purple]80[/purple][teal]) {[/teal] [navy]$y[/navy][teal]++ }[/teal]
        [COLOR=orange]when[/color][teal]([/teal][purple]75[/purple][teal]) {[/teal] [navy]$x[/navy][teal]-- }[/teal]
        [COLOR=orange]when[/color][teal]([/teal][purple]77[/purple][teal]) {[/teal] [navy]$x[/navy][teal]++ }[/teal]
        [COLOR=orange]default[/color] [teal]{[/teal] [b]print[/b] [i][green]'something else'[/green][/i] [teal]}[/teal]
    [teal]}[/teal]
[teal]}[/teal]

[b]print[/b] [i][green]"$x : $y\n"[/green][/i][teal];[/teal] [gray]# outputs 12 : 13[/gray]

Or you can use 1 array with 2 elements for the 2 coordinates and use 2 expressions : 1 to choose the array item to change and 1 to calculate the direction :

Perl:
[navy]@c[/navy] [teal]= ([/teal][purple]10[/purple][teal],[/teal] [purple]10[/purple][teal]);[/teal]
[b]foreach[/b] [navy]$key[/navy] [teal]([/teal][purple]72[/purple][teal],[/teal] [purple]80[/purple][teal],[/teal] [purple]75[/purple][teal],[/teal] [purple]77[/purple][teal],[/teal] [purple]80[/purple][teal],[/teal] [purple]77[/purple][teal],[/teal] [purple]80[/purple][teal],[/teal] [purple]77[/purple][teal],[/teal] [purple]80[/purple][teal]) {[/teal]
    [COLOR=orange]given[/color] [teal]([/teal][navy]$key[/navy][teal]) {[/teal]
        [COLOR=orange]when[/color][teal]([[/teal][purple]72[/purple][teal],[/teal] [purple]80[/purple][teal],[/teal] [purple]75[/purple][teal],[/teal] [purple]77[/purple][teal]]) {[/teal] [navy]$c[/navy][teal][[/teal][b]abs[/b][teal]([/teal][navy]$key[/navy] [teal]-[/teal] [purple]76[/purple][teal]) >[/teal] [purple]1[/purple][teal]] += ([/teal][navy]$key[/navy] [teal]>[/teal] [purple]76[/purple][teal]) *[/teal] [purple]2[/purple] [teal]-[/teal] [purple]1[/purple] [teal]}[/teal]
        [COLOR=orange]default[/color] [teal]{[/teal] [b]print[/b] [i][green]'something else'[/green][/i] [teal]}[/teal]
    [teal]}[/teal]
[teal]}[/teal]

[b]print[/b] [i][green]"$c[0] : $c[1]\n"[/green][/i][teal];[/teal] [gray]# outputs 12 : 13[/gray]

The 1[sup]st[/sup] is readable, the 2[sup]nd[/sup] is faster. At least in IS-Basic. Of course, this is probably not true / not obvious for modern machines and languages.

The conclusion ? I prefer compact code because my experiences taught me to appreciate them. You better do how your boss / employer prefers.


Feherke.
feherke.ga
 
Thank you, Feherke, for your explanation. It helps a lot!
 
Hi Feherke,

I want to follow up on this thread.

Let's say hostname() returns a host w/o domain name like this: foo.bar. I have to admit this is a rare hostname and I have never seen it before. But it's possible, right?

My question is how to still return the $from as 'foo@bar.xyz.com'? I noticed that the current implementation would return foo.bar@xyz.com. And this should be ok. However, for the sake of learning one-liner implementation, could you please show me how to return 'foo@bar.xyz.com'?

I just want to learn how to write a sophisticated one-liner perl.

Many thanks!
 
Hi Feherke,

Sorry for that I did not make myself clear. Let me restate my question:

The hostname() may return one of the following four values:
1) foo
2) foo.xyz.com
3) foo.bar.xyz.com
4) foo.bar

In either case, I want to return $from as foo@xyz.com or foo@bar.xyz.com in one-liner perl.
Your original solution handles the first three cases well, but not the forth case (I know it's a rare one and I did not mention this case in my original thread).

Could you please show me an enhanced one-liner implementation to include the forth case?

Thanks.
 
Hi

This still not explains the rule : what to check and where to cut.

Anyway, let us try this :
Code:
[b]my[/b] [navy]$from[/navy] [teal]=[/teal] [navy]$host[/navy] [teal]=~[/teal] [i][green]/\Q$char\E(.*?)(\Q$domain\E)?$/[/green][/i] [teal]?[/teal] [i][green]"$`\@$1"[/green][/i] [teal]. ([/teal][navy]$2[/navy] [teal]||[/teal] [i][green]".$domain"[/green][/i][teal]) :[/teal] [i][green]"$host\@$domain"[/green][/i][teal];[/teal]

Feherke.
feherke.ga
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top