Perl, 갭이 있는 리스트에 대해 map과 foreach 내에서 $_ 조작할 때

raymundo의 이미지

자게에 언급된 코드골프때문에 평소에 잘 쓰지 않던 map 을 가지고 끙끙대고 있는데요. ( for(@a){} 보다는 map{}@a 가 더 짧으니까 ^^)

뜻하지 않은 에러가 자꾸 나서 왜 그런지 살펴보니 for와 map에서 좀 다르게 동작하는 부분이 있군요.

      2 $array1[0] = 0;
      3 $array1[9] = 9;          # now $array1 = (0, undef, undef, ... , 9);
      4 print "@array1", "\n";   # 0 "" "" ... "" 9
      5 foreach (@array1) {
      6     $_ *= 10             # $array1 = (0, 0, 0, ... , 90)
      7 }
      8 print "@array1", "\n";   # 0 0 0 ... 0 90

3번 라인에서 인덱스9 원소를 할당했으니, 인덱스1에서 8까지는 자동으로 생성되면서 값이 undef이 되는 걸로 알고 있는데, 이렇게 undef이 되는 시점이 정확히 언제인지 좀 묘해집니다.

어쨌거나, 4번 라인의 출력은 undef값이 널 스트링 취급되어서 0과 9만 나옵니다. (중간에 스페이스와 널스트링이 번갈아 나오니 몇 칸 떨어져서 나오겠죠.)

0         9

5-7번 라인에서 $_는 @array1의 각 원소의 alias가 되고, 10을 곱해주니 undef이던 게 0으로 취급되어서 결과적으로 0.

8번 라인에서 출력하면 이제는

0 0 0 0 0 0 0 0 0 90

이 되겠죠.

여기까지는 그러려니 하겠는데... map을 쓰면 다르더라고요.

     11 $array2[0] = 0;
     12 $array2[9] = 9;
     13 print "@array2", "\n";   # 0 "" "" ... "" 9
     14 map { $_ *= 10 } @array2; # ERROR
     15 print "@array2", "\n";

이건 14번째 라인에서 에러 납니다.
Modification of a read-only value attempted at ./t2.pl line 14.

만일 13번 라인이 없을 때만 에러가 나고 있으면 에러가 안 난다면 오히려 수긍을 할 수도 있을 것 같은데, (일단 읽는 연산을 해야만 해당 인덱스가 생성된다는 식으로) 13번 라인에서는 잘 출력해놓고는 나중에 값을 바꾸려고 하면 에러가 나니 신기하군요.

애초에 map의 취지(?)가 배열의 값을 바꾸는 것보다는, 주어진 리스트를 가지고 새로운 리스트를 만들어내는 것이긴 합니다만, 위에서 보여주는 동작의 차이는 버그라고 봐야 되지 않을까 싶기도??

raymundo의 이미지

아래 링크의 답변에 의하면 버그 맞대요. 제일 정확히 이유를 설명해주는 것 같네요. 버그라고 볼 지 feature라고 볼지는 논외로 치더라도...

http://groups.google.co.kr/group/comp.lang.perl.misc/tree/browse_frm/thread/2ae0ae0b6060cfcb/68cb746db33da09f?rnum=1&hl=ko&_done=%2Fgroup%2Fcomp.lang.perl.misc%2Fbrowse_frm%2Fthread%2F2ae0ae0b6060cfcb%2F68cb746db33da09f%3Ftvc%3D1%26hl%3Dko%26#doc_59de1e5bb1b11261

좋은 하루 되세요!

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.