Return encoding of the source.
Hash#filter
is an alias for Hash#select
.
Returns a new Hash object whose entries are those for which the block returns a truthy value:
h = {foo: 0, bar: 1, baz: 2} h.select {|key, value| value < 2 } # => {:foo=>0, :bar=>1}
Returns a new Enumerator if no block given:
h = {foo: 0, bar: 1, baz: 2} e = h.select # => #<Enumerator: {:foo=>0, :bar=>1, :baz=>2}:select> e.each {|key, value| value < 2 } # => {:foo=>0, :bar=>1}
Hash#filter!
is an alias for Hash#select!
.
Returns self
, whose entries are those for which the block returns a truthy value:
h = {foo: 0, bar: 1, baz: 2} h.select! {|key, value| value < 2 } => {:foo=>0, :bar=>1}
Returns nil
if no entries were removed.
Returns a new Enumerator if no block given:
h = {foo: 0, bar: 1, baz: 2} e = h.select! # => #<Enumerator: {:foo=>0, :bar=>1, :baz=>2}:select!> e.each { |key, value| value < 2 } # => {:foo=>0, :bar=>1}
ENV.filter
is an alias for ENV.select
.
Yields each environment variable name and its value as a 2-element Array
, returning a Hash
of the names and values for which the block returns a truthy value:
ENV.replace('foo' => '0', 'bar' => '1', 'baz' => '2') ENV.select { |name, value| name.start_with?('b') } # => {"bar"=>"1", "baz"=>"2"} ENV.filter { |name, value| name.start_with?('b') } # => {"bar"=>"1", "baz"=>"2"}
Returns an Enumerator
if no block given:
e = ENV.select # => #<Enumerator: {"bar"=>"1", "baz"=>"2", "foo"=>"0"}:select> e.each { |name, value | name.start_with?('b') } # => {"bar"=>"1", "baz"=>"2"} e = ENV.filter # => #<Enumerator: {"bar"=>"1", "baz"=>"2", "foo"=>"0"}:filter> e.each { |name, value | name.start_with?('b') } # => {"bar"=>"1", "baz"=>"2"}
ENV.filter!
is an alias for ENV.select!
.
Yields each environment variable name and its value as a 2-element Array
, deleting each entry for which the block returns false
or nil
, and returning ENV
if any deletions made, or nil
otherwise:
ENV.replace('foo' => '0', 'bar' => '1', 'baz' => '2') ENV.select! { |name, value| name.start_with?('b') } # => ENV ENV # => {"bar"=>"1", "baz"=>"2"} ENV.select! { |name, value| true } # => nil ENV.replace('foo' => '0', 'bar' => '1', 'baz' => '2') ENV.filter! { |name, value| name.start_with?('b') } # => ENV ENV # => {"bar"=>"1", "baz"=>"2"} ENV.filter! { |name, value| true } # => nil
Returns an Enumerator
if no block given:
ENV.replace('foo' => '0', 'bar' => '1', 'baz' => '2') e = ENV.select! # => #<Enumerator: {"bar"=>"1", "baz"=>"2"}:select!> e.each { |name, value| name.start_with?('b') } # => ENV ENV # => {"bar"=>"1", "baz"=>"2"} e.each { |name, value| true } # => nil ENV.replace('foo' => '0', 'bar' => '1', 'baz' => '2') e = ENV.filter! # => #<Enumerator: {"bar"=>"1", "baz"=>"2"}:filter!> e.each { |name, value| name.start_with?('b') } # => ENV ENV # => {"bar"=>"1", "baz"=>"2"} e.each { |name, value| true } # => nil
Waits for the first ractor to have something in its outgoing port, reads from this ractor, and returns that ractor and the object received.
r1 = Ractor.new {Ractor.yield 'from 1'} r2 = Ractor.new {Ractor.yield 'from 2'} r, obj = Ractor.select(r1, r2) puts "received #{obj.inspect} from #{r.inspect}" # Prints: received "from 1" from #<Ractor:#2 test.rb:1 running>
If one of the given ractors is the current ractor, and it would be selected, r
will contain :receive
symbol instead of the ractor object.
r1 = Ractor.new(Ractor.current) do |main| main.send 'to main' Ractor.yield 'from 1' end r2 = Ractor.new do Ractor.yield 'from 2' end r, obj = Ractor.select(r1, r2, Ractor.current) puts "received #{obj.inspect} from #{r.inspect}" # Prints: received "to main" from :receive
If yield_value
is provided, that value may be yielded if another Ractor
is calling take
. In this case, the pair [:yield, nil]
would be returned:
r1 = Ractor.new(Ractor.current) do |main| puts "Received from main: #{main.take}" end puts "Trying to select" r, obj = Ractor.select(r1, Ractor.current, yield_value: 123) wait puts "Received #{obj.inspect} from #{r.inspect}"
This will print:
Trying to select Received from main: 123 Received nil from :yield
move
boolean flag defines whether yielded value should be copied (default) or moved.
Invokes system call select(2), which monitors multiple file descriptors, waiting until one or more of the file descriptors becomes ready for some class of I/O operation.
Not implemented on all platforms.
Each of the arguments read_ios
, write_ios
, and error_ios
is an array of IO
objects.
Argument timeout
is an integer timeout interval in seconds.
The method monitors the IO objects given in all three arrays, waiting for some to be ready; returns a 3-element array whose elements are:
An array of the objects in read_ios
that are ready for reading.
An array of the objects in write_ios
that are ready for writing.
An array of the objects in error_ios
have pending exceptions.
If no object becomes ready within the given timeout
, nil
is returned.
IO.select peeks the buffer of IO objects for testing readability. If the IO buffer is not empty, IO.select immediately notifies readability. This “peek” only happens for IO objects. It does not happen for IO-like objects such as OpenSSL::SSL::SSLSocket
.
The best way to use IO.select is invoking it after non-blocking methods such as read_nonblock, write_nonblock, etc. The methods raise an exception which is extended by IO::WaitReadable
or IO::WaitWritable
. The modules notify how the caller should wait with IO.select. If IO::WaitReadable
is raised, the caller should wait for reading. If IO::WaitWritable
is raised, the caller should wait for writing.
So, blocking read (readpartial) can be emulated using read_nonblock and IO.select as follows:
begin result = io_like.read_nonblock(maxlen) rescue IO::WaitReadable IO.select([io_like]) retry rescue IO::WaitWritable IO.select(nil, [io_like]) retry end
Especially, the combination of non-blocking methods and IO.select is preferred for IO
like objects such as OpenSSL::SSL::SSLSocket
. It has to_io method to return underlying IO
object. IO.select
calls to_io to obtain the file descriptor to wait.
This means that readability notified by IO.select doesn’t mean readability from OpenSSL::SSL::SSLSocket
object.
The most likely situation is that OpenSSL::SSL::SSLSocket
buffers some data. IO.select doesn’t see the buffer. So IO.select can block when OpenSSL::SSL::SSLSocket#readpartial
doesn’t block.
However, several more complicated situations exist.
SSL is a protocol which is sequence of records. The record consists of multiple bytes. So, the remote side of SSL sends a partial record, IO.select
notifies readability but OpenSSL::SSL::SSLSocket
cannot decrypt a byte and OpenSSL::SSL::SSLSocket#readpartial
will block.
Also, the remote side can request SSL renegotiation which forces the local SSL engine to write some data. This means OpenSSL::SSL::SSLSocket#readpartial
may invoke write system call and it can block. In such a situation, OpenSSL::SSL::SSLSocket#read_nonblock
raises IO::WaitWritable
instead of blocking. So, the caller should wait for ready for writability as above example.
The combination of non-blocking methods and IO.select is also useful for streams such as tty, pipe socket socket when multiple processes read from a stream.
Finally, Linux kernel developers don’t guarantee that readability of select(2) means readability of following read(2) even for a single process; see select(2)
Invoking IO.select before IO#readpartial
works well as usual. However it is not the best way to use IO.select.
The writability notified by select(2) doesn’t show how many bytes are writable. IO#write
method blocks until given whole string is written. So, IO#write(two or more bytes)
can block after writability is notified by IO.select. IO#write_nonblock
is required to avoid the blocking.
Blocking write (write) can be emulated using write_nonblock and IO.select
as follows: IO::WaitReadable
should also be rescued for SSL renegotiation in OpenSSL::SSL::SSLSocket
.
while 0 < string.bytesize begin written = io_like.write_nonblock(string) rescue IO::WaitReadable IO.select([io_like]) retry rescue IO::WaitWritable IO.select(nil, [io_like]) retry end string = string.byteslice(written..-1) end
Example:
rp, wp = IO.pipe mesg = "ping " 100.times { # IO.select follows IO#read. Not the best way to use IO.select. rs, ws, = IO.select([rp], [wp]) if r = rs[0] ret = r.read(5) print ret case ret when /ping/ mesg = "pong\n" when /pong/ mesg = "ping " end end if w = ws[0] w.write(mesg) end }
Output:
ping pong ping pong ping pong (snipped) ping
Returns an array containing elements selected by the block.
With a block given, calls the block with successive elements; returns an array of those elements for which the block returns a truthy value:
(0..9).select {|element| element % 3 == 0 } # => [0, 3, 6, 9] a = {foo: 0, bar: 1, baz: 2}.select {|key, value| key.start_with?('b') } a # => {:bar=>1, :baz=>2}
With no block given, returns an Enumerator.
Related: reject
.
Returns an array of objects returned by the block.
With a block given, calls the block with successive elements; returns an array of the objects returned by the block:
(0..4).map {|i| i*i } # => [0, 1, 4, 9, 16] {foo: 0, bar: 1, baz: 2}.map {|key, value| value*2} # => [0, 2, 4]
With no block given, returns an Enumerator.
Generates a hex-encoded version of a given string.
Returns the Base64-encoded version of bin
. This method complies with RFC 2045. Line feeds are added to every 60 encoded characters.
require 'base64' Base64.encode64("Now is the time for all good coders\nto learn Ruby")
Generates:
Tm93IGlzIHRoZSB0aW1lIGZvciBhbGwgZ29vZCBjb2RlcnMKdG8gbGVhcm4g UnVieQ==
Detach the process from controlling terminal and run in the background as system daemon. Unless the argument nochdir is true (i.e. non false), it changes the current working directory to the root (“/”). Unless the argument noclose is true, daemon() will redirect standard input, standard output and standard error to /dev/null. Return zero on success, or raise one of Errno::*.
Returns the destination encoding name as a string.
Returns the destination encoding name as a string.
Clear recorded tracing information.
Takes a token and gets the next token in the Negotiate authentication chain. Token can be Base64
encoded or not. The token can include the “Negotiate” header and it will be stripped. Does not indicate if SEC_I_CONTINUE or SEC_E_OK was returned. Token returned is Base64
encoded w/ all new lines removed.
Like Enumerable#map
, but chains operation to be lazy-evaluated.
(1..Float::INFINITY).lazy.map {|i| i**2 } #=> #<Enumerator::Lazy: #<Enumerator::Lazy: 1..Infinity>:map> (1..Float::INFINITY).lazy.map {|i| i**2 }.first(3) #=> [1, 4, 9]
Like Enumerable#select
, but chains operation to be lazy-evaluated.