⚝
One Hat Cyber Team
⚝
Your IP:
216.73.216.133
Server IP:
185.119.109.197
Server:
Linux managedhosting.chostar.me 5.15.0-160-generic #170-Ubuntu SMP Wed Oct 1 10:06:56 UTC 2025 x86_64
Server Software:
Apache
PHP Version:
8.1.33
Buat File
|
Buat Folder
Eksekusi
Dir :
~
/
usr
/
share
/
ri
/
3.0.0
/
system
/
Proc
/
View File Name :
cdesc-Proc.ri
U:RDoc::NormalClass[iI" Proc:ET@I"Object;To:RDoc::Markup::Document:@parts[o;;[To:RDoc::Markup::Paragraph;[ I"QA +Proc+ object is an encapsulation of a block of code, which can be stored ;TI"Qin a local variable, passed to a method or another Proc, and can be called. ;TI"GProc is an essential concept in Ruby and a core of its functional ;TI"programming features.;To:RDoc::Markup::BlankLine o:RDoc::Markup::Verbatim;[I"#square = Proc.new {|x| x**2 } ;TI" ;TI"square.call(3) #=> 9 ;TI"# shorthands: ;TI"square.(3) #=> 9 ;TI"square[3] #=> 9 ;T:@format0o; ;[I"OProc objects are _closures_, meaning they remember and can use the entire ;TI"(context in which they were created.;T@o;;[I"def gen_times(factor) ;TI"Z Proc.new {|n| n*factor } # remembers the value of factor at the moment of creation ;TI" end ;TI" ;TI"times3 = gen_times(3) ;TI"times5 = gen_times(5) ;TI" ;TI"*times3.call(12) #=> 36 ;TI"*times5.call(5) #=> 25 ;TI"*times3.call(times5.call(4)) #=> 60 ;T;0S:RDoc::Markup::Heading: leveli: textI" Creation;T@o; ;[I"/There are several methods to create a Proc;T@o:RDoc::Markup::List: @type:BULLET:@items[ o:RDoc::Markup::ListItem:@label0;[o; ;[I"$Use the Proc class constructor:;T@o;;[I""proc1 = Proc.new {|x| x**2 } ;T;0o;;0;[o; ;[I";Use the Kernel#proc method as a shorthand of Proc.new:;T@o;;[I"proc2 = proc {|x| x**2 } ;T;0o;;0;[o; ;[I"LReceiving a block of code into proc argument (note the
&
):;T@o;;[ I"def make_proc(&block) ;TI" block ;TI" end ;TI" ;TI"#proc3 = make_proc {|x| x**2 } ;T;0o;;0;[o; ;[I"KConstruct a proc with lambda semantics using the Kernel#lambda method ;TI"0(see below for explanations about lambdas):;T@o;;[I""lambda1 = lambda {|x| x**2 } ;T;0o;;0;[o; ;[I"RUse the Lambda literal syntax (also constructs a proc with lambda semantics):;T@o;;[I"lambda2 = ->(x) { x**2 } ;T;0S; ;i;I"$Lambda and non-lambda semantics;T@o; ;[I"MProcs are coming in two flavors: lambda and non-lambda (regular procs). ;TI"Differences are:;T@o;;;;[ o;;0;[o; ;[I"BIn lambdas, +return+ and +break+ means exit from this lambda;;To;;0;[o; ;[I"DIn non-lambda procs, +return+ means exit from embracing method ;TI"E(and will throw +LocalJumpError+ if invoked outside the method);;To;;0;[o; ;[I"XIn non-lambda procs, +break+ means exit from the method which the block given for. ;TI"K(and will throw +LocalJumpError+ if invoked after the method returns);;To;;0;[o; ;[I"NIn lambdas, arguments are treated in the same way as in methods: strict, ;TI";with +ArgumentError+ for mismatching argument number, ;TI"+and no additional argument processing;;To;;0;[o; ;[ I"GRegular procs accept arguments more generously: missing arguments ;TI"Lare filled with +nil+, single Array arguments are deconstructed if the ;TI"Hproc has multiple arguments, and there is no error raised on extra ;TI"arguments.;T@o; ;[I"Examples:;T@o;;[:I"5# +return+ in non-lambda proc, +b+, exits +m2+. ;TI"H# (The block +{ return }+ is given for +m1+ and embraced by +m2+.) ;TI"`$a = []; def m1(&b) b.call; $a << :m1 end; def m2() m1 { return }; $a << :m2 end; m2; p $a ;TI"#=> [] ;TI" ;TI"4# +break+ in non-lambda proc, +b+, exits +m1+. ;TI"G# (The block +{ break }+ is given for +m1+ and embraced by +m2+.) ;TI"_$a = []; def m1(&b) b.call; $a << :m1 end; def m2() m1 { break }; $a << :m2 end; m2; p $a ;TI"#=> [:m2] ;TI" ;TI"8# +next+ in non-lambda proc, +b+, exits the block. ;TI"F# (The block +{ next }+ is given for +m1+ and embraced by +m2+.) ;TI"^$a = []; def m1(&b) b.call; $a << :m1 end; def m2() m1 { next }; $a << :m2 end; m2; p $a ;TI"#=> [:m1, :m2] ;TI" ;TI"C# Using +proc+ method changes the behavior as follows because ;TI"B# The block is given for +proc+ method and embraced by +m2+. ;TI"g$a = []; def m1(&b) b.call; $a << :m1 end; def m2() m1(&proc { return }); $a << :m2 end; m2; p $a ;TI"#=> [] ;TI"f$a = []; def m1(&b) b.call; $a << :m1 end; def m2() m1(&proc { break }); $a << :m2 end; m2; p $a ;TI"0# break from proc-closure (LocalJumpError) ;TI"e$a = []; def m1(&b) b.call; $a << :m1 end; def m2() m1(&proc { next }); $a << :m2 end; m2; p $a ;TI"#=> [:m1, :m2] ;TI" ;TI"J# +return+, +break+ and +next+ in the stubby lambda exits the block. ;TI"'# (+lambda+ method behaves same.) ;TI"K# (The block is given for stubby lambda syntax and embraced by +m2+.) ;TI"e$a = []; def m1(&b) b.call; $a << :m1 end; def m2() m1(&-> { return }); $a << :m2 end; m2; p $a ;TI"#=> [:m1, :m2] ;TI"d$a = []; def m1(&b) b.call; $a << :m1 end; def m2() m1(&-> { break }); $a << :m2 end; m2; p $a ;TI"#=> [:m1, :m2] ;TI"c$a = []; def m1(&b) b.call; $a << :m1 end; def m2() m1(&-> { next }); $a << :m2 end; m2; p $a ;TI"#=> [:m1, :m2] ;TI" ;TI")p = proc {|x, y| "x=#{x}, y=#{y}" } ;TI"&p.call(1, 2) #=> "x=1, y=2" ;TI";p.call([1, 2]) #=> "x=1, y=2", array deconstructed ;TI"@p.call(1, 2, 8) #=> "x=1, y=2", extra argument discarded ;TI"Gp.call(1) #=> "x=1, y=", nil substituted instead of error ;TI" ;TI"+l = lambda {|x, y| "x=#{x}, y=#{y}" } ;TI"&l.call(1, 2) #=> "x=1, y=2" ;TI"Xl.call([1, 2]) # ArgumentError: wrong number of arguments (given 1, expected 2) ;TI"Xl.call(1, 2, 8) # ArgumentError: wrong number of arguments (given 3, expected 2) ;TI"Xl.call(1) # ArgumentError: wrong number of arguments (given 1, expected 2) ;TI" ;TI"def test_return ;TI"M -> { return 3 }.call # just returns from lambda into method body ;TI"7 proc { return 4 }.call # returns from method ;TI" return 5 ;TI" end ;TI" ;TI"*test_return # => 4, return from proc ;T;0o; ;[I"NLambdas are useful as self-sufficient functions, in particular useful as ;TI"Marguments to higher-order functions, behaving exactly like Ruby methods.;T@o; ;[I"1Procs are useful for implementing iterators:;T@o;;[ I"def test ;TI"E [[1, 2], [3, 4], [5, 6]].map {|a, b| return a if a + b > 10 } ;TI"E # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ;TI" end ;T;0o; ;[ I"PInside +map+, the block of code is treated as a regular (non-lambda) proc, ;TI"Lwhich means that the internal arrays will be deconstructed to pairs of ;TI"Jarguments, and +return+ will exit from the method +test+. That would ;TI",not be possible with a stricter lambda.;T@o; ;[I"UYou can tell a lambda from a regular proc by using the #lambda? instance method.;T@o; ;[I"QLambda semantics is typically preserved during the proc lifetime, including ;TI"6
&
-deconstruction to a block of code:;T@o;;[ I"p = proc {|x, y| x } ;TI"l = lambda {|x, y| x } ;TI")[[1, 2], [3, 4]].map(&p) #=> [1, 3] ;TI"_[[1, 2], [3, 4]].map(&l) # ArgumentError: wrong number of arguments (given 1, expected 2) ;T;0o; ;[I"IThe only exception is dynamic method definition: even if defined by ;TI"Ppassing a non-lambda proc, methods still have normal semantics of argument ;TI"checking.;T@o;;[ I" class C ;TI"# define_method(:e, &proc {}) ;TI" end ;TI"*C.new.e(1,2) #=> ArgumentError ;TI"1C.new.method(:e).to_proc.lambda? #=> true ;T;0o; ;[I"MThis exception ensures that methods never have unusual argument passing ;TI"Kconventions, and makes it easy to have wrappers defining methods that ;TI"behave as usual.;T@o;;[ I" class C ;TI"" def self.def2(name, &body) ;TI"$ define_method(name, &body) ;TI" end ;TI" ;TI" def2(:f) {} ;TI" end ;TI"*C.new.f(1,2) #=> ArgumentError ;T;0o; ;[I"IThe wrapper
def2
receives _body_ as a non-lambda proc, ;TI"5yet defines a method which has normal semantics.;T@S; ;i;I")Conversion of other objects to procs;T@o; ;[I"KAny object that implements the +to_proc+ method can be converted into ;TI"Aa proc by the
&
operator, and therefore can be ;TI"consumed by iterators.;T@o;;[I"class Greeter ;TI" def initialize(greeting) ;TI" @greeting = greeting ;TI" end ;TI" ;TI" def to_proc ;TI"1 proc {|name| "#{@greeting}, #{name}!" } ;TI" end ;TI" end ;TI" ;TI"hi = Greeter.new("Hi") ;TI"hey = Greeter.new("Hey") ;TI"?["Bob", "Jane"].map(&hi) #=> ["Hi, Bob!", "Hi, Jane!"] ;TI"A["Bob", "Jane"].map(&hey) #=> ["Hey, Bob!", "Hey, Jane!"] ;T;0o; ;[I"EOf the Ruby core classes, this method is implemented by Symbol, ;TI"Method, and Hash.;T@o;;[ I"-:to_s.to_proc.call(1) #=> "1" ;TI"4[1, 2].map(&:to_s) #=> ["1", "2"] ;TI" ;TI"0method(:puts).to_proc.call(1) # prints 1 ;TI"3[1, 2].each(&method(:puts)) # prints 1, 2 ;TI" ;TI"/{test: 1}.to_proc.call(:test) #=> 1 ;TI";%i[test many keys].map(&{test: 1}) #=> [1, nil, nil] ;T;0S; ;i;I"Orphaned Proc;T@o; ;[ I"4+return+ and +break+ in a block exit a method. ;TI"FIf a Proc object is generated from the block and the Proc object ;TI"Nsurvives until the method is returned, +return+ and +break+ cannot work. ;TI"?In such case, +return+ and +break+ raises LocalJumpError. ;TI"GA Proc object in such situation is called as orphaned Proc object.;T@o; ;[I"INote that the method to exit is different for +return+ and +break+. ;TI"RThere is a situation that orphaned for +break+ but not orphaned for +return+.;T@o;;[ I"Adef m1(&b) b.call end; def m2(); m1 { return } end; m2 # ok ;TI"@def m1(&b) b.call end; def m2(); m1 { break } end; m2 # ok ;TI" ;TI"Adef m1(&b) b end; def m2(); m1 { return }.call end; m2 # ok ;TI"Ldef m1(&b) b end; def m2(); m1 { break }.call end; m2 # LocalJumpError ;TI" ;TI"Mdef m1(&b) b end; def m2(); m1 { return } end; m2.call # LocalJumpError ;TI"Ldef m1(&b) b end; def m2(); m1 { break } end; m2.call # LocalJumpError ;T;0o; ;[I"CSince +return+ and +break+ exits the block itself in lambdas, ;TI" lambdas cannot be orphaned.;T@S; ;i;I"Numbered parameters;T@o; ;[I"MNumbered parameters are implicitly defined block parameters intended to ;TI"#simplify writing short blocks:;T@o;;[I"# Explicit parameter: ;TI"Q%w[test me please].each { |str| puts str.upcase } # prints TEST, ME, PLEASE ;TI"4(1..5).map { |i| i**2 } # => [1, 4, 9, 16, 25] ;TI" ;TI"# Implicit parameter: ;TI"J%w[test me please].each { puts _1.upcase } # prints TEST, ME, PLEASE ;TI"1(1..5).map { _1**2 } # => [1, 4, 9, 16, 25] ;T;0o; ;[I"5Parameter names from +_1+ to +_9+ are supported:;T@o;;[I"G[10, 20, 30].zip([40, 50, 60], [70, 80, 90]).map { _1 + _2 + _3 } ;TI"# => [120, 150, 180] ;T;0o; ;[I"GThough, it is advised to resort to them wisely, probably limiting ;TI"7yourself to +_1+ and +_2+, and to one-line blocks.;T@o; ;[I"FNumbered parameters can't be used together with explicitly named ;TI" ones:;T@o;;[I"$[10, 20, 30].map { |x| _1**2 } ;TI"3# SyntaxError (ordinary parameter is defined) ;T;0o; ;[I":To avoid conflicts, naming local variables or method ;TI"6arguments +_1+, +_2+ and so on, causes a warning.;T@o;;[I"_1 = 'test' ;TI"7# warning: `_1' is reserved as numbered parameter ;T;0o; ;[I">Using implicit numbered parameters affects block's arity:;T@o;;[I"p = proc { _1 + _2 } ;TI"l = lambda { _1 + _2 } ;TI"6p.parameters # => [[:opt, :_1], [:opt, :_2]] ;TI"p.arity # => 2 ;TI"6l.parameters # => [[:req, :_1], [:req, :_2]] ;TI"l.arity # => 2 ;T;0o; ;[I"5Blocks with numbered parameters can't be nested:;T@o;;[ I"0%w[test me].each { _1.each_char { p _1 } } ;TI"L# SyntaxError (numbered parameter is already used in outer block here) ;TI"2# %w[test me].each { _1.each_char { p _1 } } ;TI"# ^~ ;T;0o; ;[I"5Numbered parameters were introduced in Ruby 2.7.;T: @fileI"proc.c;T:0@omit_headings_from_table_of_contents_below0;0;0[ [ [ [[I" class;T[[:public[[I"new;TI"proc.c;T[:protected[ [:private[ [I" instance;T[[;[[I"<<;T@‰[I"==;T@‰[I"===;T@‰[I">>;T@‰[I"[];T@‰[I" arity;T@‰[I"binding;T@‰[I" call;T@‰[I" curry;T@‰[I" eql?;T@‰[I" hash;T@‰[I"inspect;T@‰[I"lambda?;T@‰[I"parameters;T@‰[I"ruby2_keywords;T@‰[I"source_location;T@‰[I"to_proc;T@‰[I" to_s;T@‰[I" yield;T@‰[;[ [;[ [ [U:RDoc::Context::Section[i 0o;;[ ;0;0[@}@}cRDoc::TopLevel