Làm cách nào để Perl's print có thể thêm một dòng mới theo mặc định?


95

Trong Perl, hầu hết các printtuyên bố của tôi có dạng

print "hello." . "\n";

Có cách nào hay để tránh giữ tất cả "\ n" phiền phức nằm xung quanh không?

Tôi biết mình có thể tạo một hàm mới, chẳng hạn như hàm myprinttự động nối thêm \ n, nhưng sẽ rất tuyệt nếu tôi có thể ghi đè lên hàm hiện có print.


10
Nếu câu trả lời của bạn bao gồm $ \, hãy đảm bảo rằng nó đi kèm với một danh sách cảnh báo về việc đặt các biến toàn cục có tác dụng ẩn. Trong khi nó trả lời câu hỏi rất thông minh và kỹ thuật, nó cũng rất nguy hiểm nếu giao cho một người mới không đủ điều kiện.
Schwern

1
perldoc perlvarmô tả hầu hết các cảnh báo, tại sao lại tin tưởng chúng ở đây?
David M

5
@David, bởi vì một số hacker ngẫu nhiên sẽ google các câu trả lời ở đây thay vì perldoc, hài lòng với chúng, và thậm chí sẽ không biết về những cảnh báo!
P Shved

2
Đó chính xác là kiểu suy luận kỳ lạ dẫn đến việc bàn ủi của tôi có nhãn cảnh báo rằng tôi không nên ủi quần áo khi đang mặc.
David M

8
Các công cụ trong cuộc sống thực có những giới hạn vật lý mà những người đã sống trong thế giới vật chất hiểu rõ một cách hợp lý. Các công cụ phần mềm không bị ràng buộc bởi những giới hạn như vậy và không có bất kỳ quy tắc nào. Họ có thể làm bất cứ điều gì và thường hành xử ngoài mong đợi, đặc biệt là đối với những người mới bắt đầu chưa học được ranh giới của những kỳ vọng hợp lý.
Ether

Câu trả lời:


99

Perl 6 có saychức năng tự động thêm vào \n.

Bạn cũng có thể sử dụng saytrong Perl 5.10 hoặc 5.12 nếu bạn thêm

use feature qw(say);

vào đầu chương trình của bạn. Hoặc bạn có thể sử dụng Modern :: Perl để lấy tính năng này và các tính năng khác.

Xem tính năng perldoc để biết thêm chi tiết.


7
Trên thực tế, tất cả những gì bạn phải làm là use 5.012;hoặc use 5.010;lấy nó nếu bạn đang chạy những ứng dụng mới hơn perlđó.
Robert P

Không an toàn khi giả định rằng trừ khi Perl 6 được đề cập cụ thể rằng câu hỏi đề cập đến Perl 5?
wobbily_col

35

Bạn có thể sử dụng -ltùy chọn trong tiêu đề she-bang:

#!/usr/bin/perl -l

$text = "hello";

print $text;
print $text;

Đầu ra:

hello
hello

3
Rất đẹp. Thêm về perlcác tùy chọn, bao gồm cả những gì -lđang làm, tại đây .
ruffin

1
Bởi vì nó là toàn cầu, đây là một thực tiễn xấu trong bất cứ điều gì ngoại trừ một lớp lót và các tập lệnh nhỏ nhất.
Schwern

24

Nếu Perl 5.10+ không phải là một tùy chọn, thì đây là một phép gần đúng nhanh chóng và sai lầm. Nó không hoàn toàn giống nhau, vì nói có một số phép thuật khi đối số đầu tiên của nó là một chốt, nhưng để in thành STDOUT:

sub say {print @_, "\n"}

say 'hello';

20

Cách bạn viết báo cáo in của mình dài dòng một cách không cần thiết. Không cần phải tách dòng mới thành chuỗi của riêng nó. Điều này là đủ.

print "hello.\n";

Nhận thức này có thể sẽ làm cho việc viết mã của bạn nói chung dễ dàng hơn.

Ngoài việc sử dụng use feature "say"hoặc use 5.10.0hoặc use Modern::Perlđể có được saytính năng tích hợp, tôi sẽ sử dụng perl5i để bật rất nhiều tính năng Perl 5 bị thiếu hợp lý theo mặc định.


9

Có lẽ bạn muốn thay đổi dấu phân tách bản ghi đầu ra của mình thành dòng cấp dữ liệu:

local $\ = "\n";

$ perl -e 'print q{hello};print q{goodbye}' | od -c
0000000    h   e   l   l   o   g   o   o   d   b   y   e                
0000014
$ perl -e '$\ = qq{\n}; print q{hello};print q{goodbye}' | od -c
0000000    h   e   l   l   o  \n   g   o   o   d   b   y   e  \n        
0000016

Cập nhật: câu trả lời của tôi nói lên khả năng hơn là khả năng tư vấn. Tôi không coi việc thêm "\ n" vào cuối dòng là một việc vặt "khó chịu", nhưng nếu ai đó thực sự muốn tránh chúng, thì đây là một cách. Nếu tôi phải duy trì một chút mã sử dụng kỹ thuật này, có lẽ tôi sẽ cấu trúc lại nó.


6
Không, xin đừng làm vậy. Mặc dù về mặt kỹ thuật là một câu trả lời đúng, nhưng việc sử dụng một biến đặc biệt cho một thứ gì đó tầm thường như đây là gánh nặng bảo trì trên đường.
tsee

1
@tsee Tôi hoàn toàn đồng ý, thực sự. Khi tôi chỉnh sửa câu trả lời của mình để chỉ ra, câu trả lời của tôi mô tả khả năng, ngay cả khi người ta không đề xuất nó như một phương pháp chung.
David M

Mối nguy thực sự đến từ thực tế là tất cả các mã bây giờ sẽ thêm dòng mới, thậm chí mã trong các mô-đun của người khác mà không mong đợi. Hãy tưởng tượng mã mạng đã gửi tin nhắn "helo\r\n"bây giờ sẽ gửi đi "helo\r\n\n".
Chà. Owens

Tất nhiên bạn luôn có thể làm cho nó địa phương để tránh ảnh hưởng đến các mã khác, nhưng vẫn muốn thực hiện chương trình con của bạn trông một chút bụi:local $\ = "\n";
redbmk

Sử dụng cờ lệnh -lrất tốt cho dòng lệnh một lớp (xem perldoc.perl.org/perlrun.html#Command-Switches ). Tôi sẽ không giới thiệu nó trong bất kỳ chương trình lớn hơn nào.
djd

4

Đây là những gì tôi tìm thấy tại https://perldoc.perl.org/perlvar.html :

$ \ Dấu phân tách bản ghi đầu ra cho toán tử in. Nếu được xác định, giá trị này được in sau đối số cuối cùng của bản in. Mặc định là undef.

Bạn không thể gọi output_record_separator () trên một xử lý, chỉ như một phương thức tĩnh. Xem IO :: Xử lý.

Ghi nhớ: bạn đặt $ \ thay vì thêm "\ n" vào cuối bản in. Ngoài ra, nó giống như $ /, nhưng nó là thứ bạn nhận được "trả lại" từ Perl.

thí dụ:

$\ = "\n";
print "a newline will be appended to the end of this line automatically";


1

Nếu bạn bị mắc kẹt với trước 5.10, thì các giải pháp được cung cấp ở trên sẽ không tái tạo đầy đủ saychức năng. Ví dụ

sub say { print @_, "\n"; }

Sẽ không hoạt động với các lời gọi như

say for @arr;

hoặc là

for (@arr) {
    say;
}

... bởi vì hàm trên không hoạt động trên hàm $_like toàn cục ngầm định printsayhàm thực .

Để sao chép chặt chẽ hơn perl 5.10+, saybạn muốn chức năng này

sub say {
    if (@_) { print @_, "\n"; }
    else { print $_, "\n"; }
}

Mà bây giờ hoạt động như thế này

my @arr = qw( alpha beta gamma );
say @arr;
# OUTPUT
# alphabetagamma
#
say for @arr;
# OUTPUT
# alpha
# beta
# gamma
#

Nội saytrang trong perl6 hoạt động hơi khác một chút. Gọi nó bằng say @arrhoặc @arr.saysẽ không chỉ nối các mục mảng mà thay vào đó in chúng được phân tách bằng dấu phân tách danh sách. Để sao chép điều này trong perl5, bạn sẽ làm điều này

sub say {
    if (@_) { print join($", @_) . "\n"; }
    else { print $_ . "\n"; }
}

$"là biến phân tách danh sách chung hoặc nếu bạn đang sử dụng English.pmthì là$LIST_SEPARATOR

Bây giờ nó sẽ hoạt động giống perl6 hơn, giống như vậy

say @arr;
# OUTPUT
# alpha beta gamma
#
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.