บล็อกและให้ผลตอบแทนใน Ruby


275

ฉันพยายามทำความเข้าใจกับบล็อกyieldและวิธีการทำงานของ Ruby

วิธีการyieldใช้งานอย่างไร แอพพลิเคชั่นของ Rails หลายตัวที่ฉันเคยใช้yieldดูแปลก ๆ

มีใครอธิบายให้ฉันฟังหรือแสดงให้ฉันดูว่าจะไปทำความเข้าใจกับพวกเขาได้ที่ไหน


2
คุณอาจจะสนใจในคำตอบของคุณลักษณะที่อัตราผลตอบแทนของรูบี้ในความสัมพันธ์กับสาขาวิชาวิทยาการคอมพิวเตอร์ แม้ว่ามันจะเป็นคำถามที่แตกต่างไปจากคำถามของคุณ แต่มันอาจทำให้เกิดความกระจ่างเกี่ยวกับเรื่องนี้
Ken Bloom

คำตอบ:


393

ใช่มันเป็นเรื่องที่น่าสับสนในตอนแรก

ในทับทิมวิธีการอาจได้รับการบล็อกรหัสเพื่อดำเนินการส่วนรหัสโดยพลการ

เมื่อเมธอดคาดว่าบล็อกมันจะเรียกใช้โดยการเรียกyieldฟังก์ชัน

สิ่งนี้มีประโยชน์มากเช่นการวนซ้ำรายการหรือเพื่อให้อัลกอริทึมแบบกำหนดเอง

นำตัวอย่างต่อไปนี้:

ฉันจะกำหนดPersonชั้นเรียนเริ่มต้นด้วยชื่อและให้do_with_nameวิธีการที่เมื่อเรียกก็จะส่งnameแอตทริบิวต์ไปยังบล็อกที่ได้รับ

class Person 
    def initialize( name ) 
         @name = name
    end

    def do_with_name 
        yield( @name ) 
    end
end

สิ่งนี้จะช่วยให้เราสามารถเรียกวิธีการนั้นและผ่านบล็อกรหัสโดยพลการ

ตัวอย่างเช่นในการพิมพ์ชื่อเราจะทำ:

person = Person.new("Oscar")

#invoking the method passing a block
person.do_with_name do |name|
    puts "Hey, his name is #{name}"
end

จะพิมพ์:

Hey, his name is Oscar

สังเกตุบล็อคได้รับเป็นตัวแปรที่เรียกว่าname(NB คุณสามารถเรียกตัวแปรนี้ได้ทุกอย่างที่คุณต้องการ แต่มันก็เหมาะสมที่จะเรียกมันname) เมื่อรหัสเรียกมันเติมพารามิเตอร์นี้มีค่าของyield@name

yield( @name )

เราสามารถให้บล็อกอื่นเพื่อทำการกระทำที่แตกต่าง ตัวอย่างเช่นย้อนกลับชื่อ:

#variable to hold the name reversed
reversed_name = ""

#invoke the method passing a different block
person.do_with_name do |name| 
    reversed_name = name.reverse
end

puts reversed_name

=> "racsO"

เราใช้วิธีการเดียวกันอย่างแน่นอน ( do_with_name) - มันเป็นเพียงบล็อกที่แตกต่างกัน

ตัวอย่างนี้เล็กน้อย ประเพณีที่น่าสนใจกว่านั้นคือการกรององค์ประกอบทั้งหมดในอาเรย์:

 days = ["monday", "tuesday", "wednesday", "thursday", "friday"]  

 # select those which start with 't' 
 days.select do | item |
     item.match /^t/
 end

=> ["tuesday", "thursday"]

หรือเราสามารถจัดเตรียมอัลกอริทึมการเรียงลำดับแบบกำหนดเองได้เช่นตามขนาดสตริง:

 days.sort do |x,y|
    x.size <=> y.size
 end

=> ["monday", "friday", "tuesday", "thursday", "wednesday"]

ฉันหวังว่านี่จะช่วยให้คุณเข้าใจได้ดีขึ้น

BTW ถ้าบล็อกเป็นตัวเลือกคุณควรเรียกว่า:

yield(value) if block_given?

หากไม่ใช่ตัวเลือกให้เรียกใช้

แก้ไข

@hmak สร้าง repl.it สำหรับตัวอย่างเหล่านี้: https://repl.it/@makstaks/blocksandyieldsrubyexample


มันพิมพ์ออกมาได้racsOอย่างไร the_name = ""
Paritosh Piplewar

2
ขออภัยชื่อเป็นตัวแปรอินสแตนซ์ที่เริ่มต้นด้วย"Oscar" (ไม่ชัดเจนมากในคำตอบ)
OscarRyz

แล้วโค้ดแบบนี้ล่ะ? person.do_with_name {|string| yield string, something_else }
f.ardelian

7
ดังนั้นในแง่ Javascripty มันเป็นวิธีมาตรฐานในการส่งกลับไปยังวิธีที่กำหนดและเรียกมัน ขอบคุณสำหรับคำอธิบาย!
yitznewton

โดยทั่วไปคือบล็อกคือน้ำตาลซินแทกซ์ที่ได้รับการปรับปรุงให้ดีขึ้นสำหรับรูปแบบกลยุทธ์ เพราะการใช้งานทั่วไปคือการให้รหัสเพื่อทำอะไรบางอย่างในบริบทของการดำเนินการอื่น ๆ แต่การปรับปรุงทับทิมเปิดทางให้กับสิ่งที่ยอดเยี่ยมเช่นการเขียน DSL โดยใช้บล็อกเพื่อส่งผ่านบริบท
Roman Bulgakov

25

ใน Ruby เมธอดสามารถตรวจสอบเพื่อดูว่าถูกเรียกในลักษณะที่บล็อกถูกจัดเตรียมเพิ่มเติมจากอาร์กิวเมนต์ปกติหรือไม่ โดยทั่วไปแล้วจะใช้block_given?วิธีนี้ แต่คุณยังสามารถอ้างถึงบล็อกเป็น Proc อย่างชัดเจนโดยการใส่เครื่องหมายแอมเปอร์แซนด์ ( &) ก่อนหน้าชื่ออาร์กิวเมนต์สุดท้าย

หากมีการเรียกใช้เมธอดด้วยบล็อกดังนั้นเมธอดสามารถyieldควบคุมบล็อก (เรียกบล็อก) ด้วยอาร์กิวเมนต์บางตัวหากจำเป็น ลองพิจารณาตัวอย่างวิธีนี้ที่สาธิต:

def foo(x)
  puts "OK: called as foo(#{x.inspect})"
  yield("A gift from foo!") if block_given?
end

foo(10)
# OK: called as foo(10)
foo(123) {|y| puts "BLOCK: #{y} How nice =)"}
# OK: called as foo(123)
# BLOCK: A gift from foo! How nice =)

หรือใช้ไวยากรณ์อาร์กิวเมนต์บล็อกพิเศษ:

def bar(x, &block)
  puts "OK: called as bar(#{x.inspect})"
  block.call("A gift from bar!") if block
end

bar(10)
# OK: called as bar(10)
bar(123) {|y| puts "BLOCK: #{y} How nice =)"}
# OK: called as bar(123)
# BLOCK: A gift from bar! How nice =)

เป็นการดีที่จะทราบวิธีการต่าง ๆ ในการเรียกบล็อก
LPing

22

เป็นไปได้มากที่บางคนจะให้คำตอบโดยละเอียดอย่างแท้จริงที่นี่ แต่ฉันพบเสมอว่าโพสต์นี้จาก Robert Sosinski เป็นคำอธิบายที่ดีเกี่ยวกับรายละเอียดปลีกย่อยระหว่างบล็อค procs & lambdas

ฉันควรเพิ่มว่าฉันเชื่อว่าโพสต์ที่ฉันลิงก์ไปนั้นเฉพาะกับทับทิม 1.8 บางสิ่งมีการเปลี่ยนแปลงใน ruby ​​1.9 เช่นตัวแปรบล็อกที่อยู่ภายในบล็อก ใน 1.8 คุณจะได้รับสิ่งต่อไปนี้:

>> a = "Hello"
=> "Hello"
>> 1.times { |a| a = "Goodbye" }
=> 1
>> a
=> "Goodbye"

ในขณะที่ 1.9 จะให้:

>> a = "Hello"
=> "Hello"
>> 1.times { |a| a = "Goodbye" }
=> 1
>> a
=> "Hello"

ฉันไม่มี 1.9 ในเครื่องนี้ดังนั้นข้างต้นอาจมีข้อผิดพลาด


คำอธิบายที่ดีในบทความนั้นมันเอาฉันเดือนตัวเลขที่ออกมาทั้งหมดใน = ของตัวเอง)
maerics

ฉันเห็นด้วย. ฉันไม่คิดว่าฉันรู้สิ่งที่อธิบายไว้ครึ่งหนึ่งจนกว่าฉันจะอ่าน
theIV

ลิงก์ที่อัปเดตคือ 404 ในตอนนี้เช่นกัน นี่คือการเชื่อมโยง Wayback เครื่อง
klenwell

@ klenwell ขอบคุณสำหรับหัวขึ้นฉันได้ปรับปรุงลิงค์อีกครั้ง
theIV

13

ฉันต้องการเรียงลำดับเพิ่มว่าทำไมคุณจะทำสิ่งต่าง ๆ เพื่อตอบคำถามที่ยอดเยี่ยมแล้ว

ไม่มีความคิดว่าคุณมาจากภาษาใด แต่สมมติว่าเป็นภาษาแบบคงที่สิ่งต่าง ๆ เช่นนี้จะดูคุ้นเคย นี่คือวิธีที่คุณอ่านไฟล์ใน java

public class FileInput {

  public static void main(String[] args) {

    File file = new File("C:\\MyFile.txt");
    FileInputStream fis = null;
    BufferedInputStream bis = null;
    DataInputStream dis = null;

    try {
      fis = new FileInputStream(file);

      // Here BufferedInputStream is added for fast reading.
      bis = new BufferedInputStream(fis);
      dis = new DataInputStream(bis);

      // dis.available() returns 0 if the file does not have more lines.
      while (dis.available() != 0) {

      // this statement reads the line from the file and print it to
        // the console.
        System.out.println(dis.readLine());
      }

      // dispose all the resources after using them.
      fis.close();
      bis.close();
      dis.close();

    } catch (FileNotFoundException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
}

ไม่สนใจสิ่งที่ผูกมัดสายน้ำทั้งหมดความคิดคือสิ่งนี้

  1. เตรียมใช้งานทรัพยากรที่ต้องล้างข้อมูล
  2. ใช้ทรัพยากร
  3. ทำให้แน่ใจว่าได้ทำความสะอาด

นี่คือวิธีที่คุณทำในทับทิม

File.open("readfile.rb", "r") do |infile|
    while (line = infile.gets)
        puts "#{counter}: #{line}"
        counter = counter + 1
    end
end

ต่างกันอย่างดุเดือด ทำลายอันนี้ลง

  1. บอกคลาส File ว่าจะเริ่มต้นทรัพยากรได้อย่างไร
  2. บอกคลาสไฟล์ว่าจะทำอย่างไรกับมัน
  3. หัวเราะกับพวก java ที่ยังพิมพ์อยู่ ;-)

ที่นี่แทนที่จะจัดการกับขั้นตอนที่หนึ่งและสองคุณจะมอบมันให้กับคลาสอื่น อย่างที่คุณสามารถเห็นได้ว่าจะลดปริมาณของรหัสที่คุณต้องเขียนลงอย่างมากซึ่งทำให้อ่านง่ายขึ้นและลดโอกาสของการรั่วไหลของหน่วยความจำหรือล็อคไฟล์ที่ไม่ได้รับการล้าง

ตอนนี้มันไม่เหมือนกับที่คุณไม่สามารถทำสิ่งที่คล้ายกันในจาวาในความเป็นจริงคนได้ทำมานานหลายสิบปีแล้ว มันเรียกว่ารูปแบบกลยุทธ์ ความแตกต่างคือไม่มีบล็อกสำหรับสิ่งที่เรียบง่ายเช่นตัวอย่างไฟล์กลยุทธ์กลายเป็น overkill เนื่องจากจำนวนคลาสและวิธีการที่คุณต้องเขียน ด้วยบล็อกมันเป็นวิธีที่เรียบง่ายและสง่างามในการทำเช่นนั้นซึ่งมันไม่สมเหตุสมผลที่จะไม่สร้างโครงสร้างโค้ดของคุณในลักษณะนั้น

นี่ไม่ใช่วิธีเดียวที่ใช้ในการบล็อก แต่ส่วนอื่น ๆ (เช่นรูปแบบของตัวสร้างซึ่งคุณสามารถเห็นได้ใน form_for api ในราง) มีลักษณะคล้ายกันมากพอที่จะเห็นได้ชัดว่าเกิดอะไรขึ้นเมื่อคุณล้อมรอบสิ่งนี้ เมื่อคุณเห็นบล็อกมักจะปลอดภัยที่จะถือว่าการเรียกใช้เมธอดเป็นสิ่งที่คุณต้องการทำและบล็อกอธิบายวิธีที่คุณต้องการทำ


5
มาทำให้มันง่ายขึ้นหน่อย: File.readlines("readfile.rb").each_with_index do |line, index| puts "#{index + 1}: #{line}" endแล้วหัวเราะให้หนักขึ้นที่พวก Java
Michael Hampton

1
@MichaelHampton หัวเราะหลังจากที่คุณอ่านไฟล์สักสองสามกิกะไบต์
akostadinov

@akostadinov ไม่ ... ที่ทำให้ฉันอยากร้องไห้!
Michael Hampton

3
@MichaelHampton หรือยังดีกว่า: IO.foreach('readfile.rb').each_with_index { |line, index| puts "#{index}: #{line}" }(บวกกับปัญหาหน่วยความจำไม่ได้)
คดีกองทุนของโมนิกา

12

ฉันพบว่าบทความนี้มีประโยชน์มาก โดยเฉพาะอย่างยิ่งตัวอย่างต่อไปนี้:

#!/usr/bin/ruby

def test
  yield 5
  puts "You are in the method test"
  yield 100
end

test {|i| puts "You are in the block #{i}"}

test do |i|
    puts "You are in the block #{i}"
end

ซึ่งควรให้ผลลัพธ์ต่อไปนี้:

You are in the block 5
You are in the method test
You are in the block 100
You are in the block 5
You are in the method test
You are in the block 100

เพื่อเป็นหลักในแต่ละครั้งที่มีการโทรที่เกิดขึ้นกับyieldทับทิมจะเรียกใช้รหัสในการบล็อกหรือภายในdo {}หากมีการระบุพารามิเตอร์ไว้yieldสิ่งนี้จะถูกจัดให้เป็นพารามิเตอร์ของdoบล็อก

สำหรับฉันนี่เป็นครั้งแรกที่ฉันเข้าใจจริงๆว่าdoบล็อกกำลังทำอะไร มันเป็นวิธีที่ฟังก์ชั่นให้การเข้าถึงโครงสร้างข้อมูลภายในไม่ว่าจะเป็นการวนซ้ำหรือการกำหนดค่าฟังก์ชั่น

ดังนั้นเมื่ออยู่ในรางคุณเขียนสิ่งต่อไปนี้:

respond_to do |format|
  format.html { render template: "my/view", layout: 'my_layout' }
end

สิ่งนี้จะเรียกใช้respond_toฟังก์ชันที่ให้ผลลัพธ์doบล็อกด้วยformatพารามิเตอร์(ภายใน) จากนั้นคุณเรียกใช้.htmlฟังก์ชันบนตัวแปรภายในนี้ซึ่งจะส่งผลให้บล็อกโค้ดเพื่อรันrenderคำสั่ง โปรดทราบว่า.htmlจะให้ผลก็ต่อเมื่อเป็นรูปแบบไฟล์ที่ร้องขอ (ด้านเทคนิค: ฟังก์ชั่นเหล่านี้ใช้งานblock.callได้จริงอย่างที่ไม่yieldเห็นจากแหล่งที่มาแต่ฟังก์ชั่นนั้นเหมือนกันให้ดูคำถามนี้สำหรับการอภิปราย) นี่เป็นวิธีการที่ฟังก์ชั่นในการเริ่มต้นใช้งาน จากนั้นดำเนินการประมวลผลถ้าจำเป็น

หรือใส่วิธีอื่นมันคล้ายกับฟังก์ชั่นที่ใช้ฟังก์ชั่นที่ไม่ระบุชื่อเป็นอาร์กิวเมนต์แล้วเรียกมันในจาวาสคริปต์


8

ใน Ruby บล็อกนั้นเป็นกลุ่มของโค้ดที่สามารถส่งผ่านและดำเนินการโดยวิธีใดก็ได้ บล็อกมักจะใช้กับวิธีการซึ่งมักจะฟีดข้อมูลให้กับพวกเขา (เป็นข้อโต้แย้ง)

บล็อกถูกนำมาใช้กันอย่างแพร่หลายในพลอยทับทิม (รวมถึงราง) และในรหัสทับทิมที่เขียนดี มันไม่ใช่วัตถุดังนั้นจึงไม่สามารถกำหนดให้กับตัวแปรได้

ไวยากรณ์พื้นฐาน

บล็อกคือชิ้นส่วนของรหัสที่ล้อมรอบด้วย {} หรือ do..end ตามแบบแผนควรใช้ซิงก์ brace แบบลอนสำหรับบล็อกบรรทัดเดียวและควรใช้ไวยากรณ์ซิงก์ .. สำหรับบล็อกหลายบรรทัด

{ # This is a single line block }

do
  # This is a multi-line block
end 

วิธีการใด ๆ สามารถรับบล็อกเป็นอาร์กิวเมนต์โดยนัย บล็อกถูกดำเนินการโดยคำสั่งผลผลิตภายในวิธีการ ไวยากรณ์พื้นฐานคือ:

def meditate
  print "Today we will practice zazen"
  yield # This indicates the method is expecting a block
end 

# We are passing a block as an argument to the meditate method
meditate { print " for 40 minutes." }

Output:
Today we will practice zazen for 40 minutes.

เมื่อถึงคำสั่งให้ผลผลิตวิธีการทำสมาธิจะให้การควบคุมกับบล็อกโค้ดภายในบล็อกนั้นจะถูกดำเนินการและการควบคุมจะถูกส่งกลับไปที่เมธอด

เมื่อเมธอดมีข้อความชี้แจงผลตอบแทนคาดว่าจะได้รับบล็อกในเวลาที่โทร หากไม่ได้จัดเตรียมบล็อกไว้จะมีข้อผิดพลาดเกิดขึ้นเมื่อถึงประกาศผลตอบแทน เราสามารถทำให้บล็อกเป็นทางเลือกและหลีกเลี่ยงข้อยกเว้นจากการเพิ่ม:

def meditate
  puts "Today we will practice zazen."
  yield if block_given? 
end meditate

Output:
Today we will practice zazen. 

ไม่สามารถส่งหลาย ๆ บล็อกไปที่เมธอดได้ แต่ละวิธีสามารถรับได้เพียงหนึ่งบล็อกเท่านั้น

ดูเพิ่มเติมได้ที่: http://www.zenruby.info/2016/04/introduction-to-blocks-in-ruby.html


นี่คือคำตอบ (เท่านั้น) ที่ทำให้ฉันเข้าใจจริงๆว่าบล็อกและผลตอบแทนคืออะไรและใช้อย่างไร
Eric Wang

5

บางครั้งฉันใช้ "ผลตอบแทน" เช่นนี้:

def add_to_http
   "http://#{yield}"
end

puts add_to_http { "www.example.com" }
puts add_to_http { "www.victim.com"}

ตกลง แต่ทำไม มีเหตุผลมากมายเช่นหนึ่งLoggerไม่ต้องทำงานบางอย่างหากผู้ใช้ไม่จำเป็นต้อง คุณควรอธิบายว่า ...
Ulysse BN

4

อัตราผลตอบแทนที่จะพูดง่าย ๆ อนุญาตให้วิธีที่คุณสร้างขึ้นเพื่อใช้และบล็อกการโทร คำหลักผลตอบแทนโดยเฉพาะคือจุดที่ 'สิ่ง' ในบล็อกจะดำเนินการ


1

มีสองจุดที่ฉันต้องการทำเกี่ยวกับผลผลิตที่นี่ ก่อนในขณะที่คำตอบมากมายที่นี่พูดถึงวิธีต่าง ๆ ในการส่งบล็อกไปยังวิธีที่ใช้ผลตอบแทนเรามาพูดถึงการควบคุมกระแส สิ่งนี้มีความเกี่ยวข้องเป็นพิเศษเนื่องจากคุณสามารถให้ผลคูณกับบล็อกได้หลายครั้ง ลองมาดูตัวอย่าง:

class Fruit
  attr_accessor :kinds

  def initialize 
    @kinds = %w(orange apple pear banana)
  end

  def each 
    puts 'inside each'
    3.times { yield (@kinds.tap {|kinds| puts "selecting from #{kinds}"} ).sample }
  end  
end

f = Fruit.new
f.each do |kind|
  puts 'inside block'
end    

=> inside each
=> selecting from ["orange", "apple", "pear", "banana"]
=> inside block
=> selecting from ["orange", "apple", "pear", "banana"]
=> inside block
=> selecting from ["orange", "apple", "pear", "banana"]
=> inside block

เมื่อแต่ละเมธอดถูกเรียกใช้จะเรียกใช้งานทีละบรรทัด ตอนนี้เมื่อเราไปถึงบล็อก 3.times บล็อกนี้จะถูกเรียก 3 ครั้ง ทุกครั้งที่มันก่อให้เกิดผลผลิต ผลผลิตนั้นเชื่อมโยงกับบล็อกที่เกี่ยวข้องกับวิธีการที่เรียกว่าแต่ละวิธี สิ่งสำคัญคือให้สังเกตว่าแต่ละครั้งที่มีการเรียกใช้ผลตอบแทนจะส่งคืนการควบคุมกลับไปยังบล็อกของแต่ละวิธีในรหัสลูกค้า เมื่อบล็อกดำเนินการเสร็จสิ้นบล็อกจะกลับสู่บล็อก 3.times และนี่เกิดขึ้น 3 ครั้ง ดังนั้นบล็อกในรหัสลูกค้าจะถูกเรียกใช้ใน 3 โอกาสที่แยกกันเนื่องจากอัตราผลตอบแทนจะถูกเรียกอย่างชัดเจน 3 ครั้ง

จุดที่สองของฉันเกี่ยวกับ enum_for และผลผลิต enum_for อินสแตนซ์คลาสของตัวแจงนับและวัตถุตัวแจงนับนี้ยังตอบสนองต่อผลผลิต

class Fruit
  def initialize
    @kinds = %w(orange apple)
  end

  def kinds
    yield @kinds.shift
    yield @kinds.shift
  end
end

f = Fruit.new
enum = f.to_enum(:kinds)
enum.next
 => "orange" 
enum.next
 => "apple" 

ดังนั้นให้สังเกตทุกครั้งที่เราเรียกใช้ชนิดด้วยตัววนซ้ำภายนอกมันจะเรียกใช้ผลตอบแทนเพียงครั้งเดียว ครั้งต่อไปที่เราเรียกมันว่ามันจะก่อให้เกิดผลผลิตต่อไปเป็นต้น

มีชิ้นอาหารอันโอชะที่น่าสนใจเกี่ยวกับ enum_for เอกสารออนไลน์ระบุสิ่งต่อไปนี้:

enum_for(method = :each, *args)  enum
Creates a new Enumerator which will enumerate by calling method on obj, passing args if any.

str = "xyz"
enum = str.enum_for(:each_byte)
enum.each { |b| puts b }    
# => 120
# => 121
# => 122

หากคุณไม่ระบุสัญลักษณ์เป็นอาร์กิวเมนต์ให้กับ enum_for ทับทิมจะขอให้ตัวแจงนับกับแต่ละวิธีของผู้รับ บางคลาสไม่มีวิธีแต่ละวิธีเช่นคลาส String

str = "I like fruit"
enum = str.to_enum
enum.next
=> NoMethodError: undefined method `each' for "I like fruit":String

ดังนั้นในกรณีของวัตถุบางอย่างที่เรียกใช้ด้วย enum_for คุณต้องชัดเจนว่าวิธีการแจกแจงของคุณคืออะไร


0

สามารถใช้Yieldเป็นบล็อกแบบไม่ระบุชื่อเพื่อส่งคืนค่าในเมธอด พิจารณารหัสต่อไปนี้:

Def Up(anarg)
  yield(anarg)
end

คุณสามารถสร้างวิธีการ "ขึ้น" ซึ่งได้รับการกำหนดหนึ่งข้อโต้แย้ง ตอนนี้คุณสามารถกำหนดอาร์กิวเมนต์นี้เพื่อให้ได้ผลลัพธ์ซึ่งจะเรียกและดำเนินการบล็อกที่เกี่ยวข้อง คุณสามารถกำหนดบล็อกหลังรายการพารามิเตอร์

Up("Here is a string"){|x| x.reverse!; puts(x)}

เมื่อการเรียกใช้เมธอด Up พร้อมด้วยอาร์กิวเมนต์จะถูกส่งไปยังตัวแปรบล็อกเพื่อประมวลผลคำขอ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.