Это nice 'n простой способ захвата вывода pp
:
require 'pp' asdf = {'a' => 1, :b => 2, 'c' => %w[ho daddy]} foo = PP.pp(asdf, '') puts foo => {"a"=>1, :b=>2, "c"=>["ho", "daddy"]}
Захват STDOUT, который является каналом по умолчанию, используемым puts
и print
, и что такие вещи, как pp
контрейлерные, немного сложнее:
require 'pp'
require 'stringio'
asdf = {'a' => 1, :b => 2, 'c' => %w[ho daddy]}
puts 'Writing to STDOUT...'
pp asdf
# remember the old STDOUT stream...
old_stdout = $stdout
# ...and create a new stream that writes to a string.
captured_stdio = StringIO.new('', 'w')
$stdout = captured_stdio
# This is all captured...
puts 'Capturing to buffer...'
pp asdf
# reset STDOUT
$stdout = old_stdout
puts 'Capturing off...'
# show what we got...
puts captured_stdio.string
И что было напечатано:
Writing to STDOUT...
{"a"=>1, :b=>2, "c"=>["ho", "daddy"]}
Capturing off...
Capturing to buffer...
{"a"=>1, :b=>2, "c"=>["ho", "daddy"]}
Последние две строки выше были сохранены в captured_stdio
, заменив это для нормального канала $stdout
. Все, что написано (что было бы STDOUT), было сохранено. Перестановка назад в исходном канале восстановила нормальную печать и остановила что-либо еще от записи на captured_stdio
.
Да, но не выделенная память, на которую он указывает. Это всего лишь 4-байтовая переменная-указатель, единственное, что от нее нужно - сохранить ее значение.
Значение - это адрес. Адрес - это то, что выделяется вручную, и его освобождение требует вызова функций, о которых компилятор не знает.
optimizedImage находится в стеке функции, поэтому он выходит за пределы области видимости после возврата из функции. Объект, на который он указывает, находится в куче, поэтому он остается там до тех пор, пока на него не будет ссылаться другой указатель.