Sự khác biệt giữa in và đặt là gì?


Câu trả lời:


377

puts thêm một dòng mới vào cuối mỗi đối số nếu chưa có một đối số.

print không thêm một dòng mới.


Ví dụ:

puts [[1,2,3], [4,5,nil]] Sẽ trở lại:

1
2
3
4
5

Trong khi đó print [[1,2,3], [4,5,nil]] sẽ trở lại:

[[1,2,3], [4,5, không]]
Lưu ý cách đặt không xuất giá trị nil trong khi in.

88
Trên thực tế, một dòng mới sau mỗi đối số. Đó là một điểm chính và không rõ ràng từ các tài liệu Ruby (vì ví dụ này chỉ có 1 đối số).
cdunn2001

3
Có một điều nữa ... mở rộng lớp mảng và ghi đè phương thức to_s. đặt không sử dụng to_s mới cho một đối tượng của lớp mới của bạn trong khi in
kapv89

1
sử dụng irb 0.9.5 đặt ("a") và đặt ("a \ n") có cùng một đầu ra trên REPL.
Marcus Junius Brutus

@ kapv89 Điều đó không đúng: Tôi vừa thử và cả hai đều in e sử dụng phương thức to_s. Chỉ p không sử dụng nó.
collimarco

6
@Fronker, đó vẫn chỉ là một đối số. Trình biên dịch nối các chuỗi liền kề.
cdunn2001

61

Một sự khác biệt lớn là nếu bạn đang hiển thị mảng. Đặc biệt là những người có NIL. Ví dụ:

print [nil, 1, 2]

cho

[nil, 1, 2]

nhưng

puts [nil, 1, 2]

cho

1
2

Lưu ý, không có mục nào xuất hiện (chỉ là một dòng trống) và mỗi mục trên một dòng khác nhau.


1
Tôi nhận thấy điều này ngày hôm nay, đã đưa tôi đến đây. Tôi muốn biết suy nghĩ về điều đó. Có vẻ như một trường hợp đặc biệt để đặt để xử lý các mảng như vậy. Tự hỏi lý do là gì ... Có phải nó giống với các ngôn ngữ khác không?
Dan Barron

Điều này hợp lý vì các lệnh sẽ xuất ra một dòng mới, vì vậy bạn có thể nghĩ về nó như lặp lại trên mảng và gọi các lệnh đặt trên mỗi dòng ... tuy nhiên, điều đó thật kỳ lạ là nó không xuất ranil
Muers

42

printxuất ra từng đối số, theo sau $,, đến $stdout, theo sau $\. Nó tương đương vớiargs.join($,) + $\

putsđặt cả hai $,$\thành "\ n" và sau đó thực hiện tương tự như print. Sự khác biệt chính là mỗi đối số là một dòng mới puts.

Bạn có thể require 'english'truy cập các biến toàn cục đó bằng các tên thân thiện với người dùng .


mẹo hay về englishlib
lacostenycoder

18

Các tài liệu API đưa ra một số gợi ý hay:

print() → nil

print(obj, ...) → nil

Viết (các) đối tượng đã cho vào ios . Trả về nil.

Các luồng phải được mở để viết. Mỗi đối tượng đã cho không phải là một chuỗi sẽ được chuyển đổi bằng cách gọi to_sphương thức của nó . Khi được gọi mà không có đối số, in nội dung của $_.

Nếu dấu phân cách trường đầu ra ( $,) thì không nil, nó được chèn giữa các đối tượng. Nếu dấu phân cách bản ghi đầu ra ( $\) thì không nil, nó được gắn vào đầu ra.

...

puts(obj, ...) → nil

Viết (các) đối tượng đã cho vào ios . Viết một dòng mới sau bất kỳ dòng nào chưa kết thúc bằng một chuỗi dòng mới. Trả về nil.

Các luồng phải được mở để viết. Nếu được gọi với một đối số mảng, hãy viết từng phần tử trên một dòng mới. Mỗi đối tượng đã cho không phải là một chuỗi hoặc mảng sẽ được chuyển đổi bằng cách gọi to_sphương thức của nó . Nếu được gọi mà không có đối số, xuất ra một dòng mới.

Thử nghiệm một chút với các điểm nêu trên, sự khác biệt dường như là:

  • Được gọi với nhiều đối số, printphân tách chúng bằng 'dấu tách trường đầu ra' $,(mặc định là không có gì) trong khi putsphân tách chúng bằng các dòng mới. putscũng đặt một dòng mới sau khi đối số cuối cùng, trong khi printkhông.

    2.1.3 :001 > print 'hello', 'world'
    helloworld => nil 
    2.1.3 :002 > puts 'hello', 'world'
    hello
    world
     => nil
    2.1.3 :003 > $, = 'fanodd'
     => "fanodd" 
    2.1.3 :004 > print 'hello', 'world'
    hellofanoddworld => nil 
    2.1.3 :005 > puts 'hello', 'world'
    hello
    world
     => nil
  • putstự động giải nén các mảng, trong khi printkhông:

    2.1.3: 001> in [1, [2, 3]], [4]
    [1, [2, 3]] [4] => không 
    2.1.3: 002> đặt [1, [2, 3]], [4]
    1
    2
    3
    4
     => không
  • printkhông có đối số được in $_(điều cuối cùng được đọc bởi gets), trong khi putsin một dòng mới:

    2.1.3 :001 > gets
    hello world
     => "hello world\n" 
    2.1.3 :002 > puts
    
     => nil 
    2.1.3 :003 > print
    hello world
     => nil
  • printghi dấu phân tách bản ghi đầu ra $\sau bất cứ thứ gì nó in, trong khi putsbỏ qua biến này:

    mark@lunchbox:~$ irb
    2.1.3 :001 > $\ = 'MOOOOOOO!'
     => "MOOOOOOO!" 
    2.1.3 :002 > puts "Oink! Baa! Cluck! "
    Oink! Baa! Cluck! 
     => nil 
    2.1.3 :003 > print "Oink! Baa! Cluck! "
    Oink! Baa! Cluck! MOOOOOOO! => nil

4

putsgọi to_stừng đối số và thêm một dòng mới vào mỗi chuỗi, nếu nó không kết thúc bằng dòng mới. printchỉ cần xuất từng đối số bằng cách gọi chúng to_s.

ví dụ puts "one two":: one two

{dòng mới}

puts "one two\n": one two

{dòng mới} #puts sẽ không thêm dòng mới vào kết quả, vì chuỗi kết thúc bằng một dòng mới

print "one two": one two

print "one two\n": one two

{dòng mới}

Và có một cách khác để xuất ra: p

Đối với mỗi đối tượng, trực tiếp viết obj.inspect theo sau là một dòng mới đến đầu ra tiêu chuẩn của chương trình.

Nó rất hữu ích để xuất thông báo gỡ lỗi. p "aa\n\t":aa\n\t


-1

Nếu bạn muốn xuất mảng trong chuỗi bằng cách sử dụng puts, bạn sẽ nhận được kết quả tương tự như khi bạn đang sử dụng print:

puts "#{[0, 1, nil]}":
[0, 1, nil]

Nhưng nếu không rút một chuỗi trích dẫn thì có. Sự khác biệt duy nhất là giữa dòng mới khi chúng tôi sử dụng puts.


1
-1 vì hai lý do. Thứ nhất, thiếu rõ ràng: Tôi không hiểu "Nhưng ..." ban đầu ở đây dự định làm gì để tiếp tục từ đó, tôi cũng không hiểu "có" trong đoạn cuối đang trả lời là gì. Thứ hai, vì thiếu tính chính xác: bạn nói rằng sử dụng printfthay vì putstrong mã ví dụ của bạn sẽ cho kết quả tương tự, nhưng thực tế thì không. Các putsbiến thể bổ sung thêm một dòng mới vào cuối trong khi printfmột không, giống như trường hợp không có mảng nội suy vào chuỗi. (Nhất thiết phải như vậy, vì phép nội suy xảy ra khi đánh giá chuỗi ký tự.)
Mark Amery

Aha! Sau khi đọc các câu trả lời khác, tôi nghĩ tôi hiểu - bạn dự định đây sẽ là câu trả lời cho stackoverflow.com/a/14534145/1709587 ? Trong mọi trường hợp, nó không thực sự đứng một câu trả lời.
Mark Amery
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.