instance_methods(nil)
?
instance_methods
returns an array of the methods of an
object, whereas instance_methods(nil)
returns the methods which are
defined in the class of the object, excluding the methods inherited
from superclasses.
rand
generate the same random number sequence?
rand
generates the same sequence every time the script runs.
You need to give a different seed by srand
to generate
different random numbers every time. srand
called without
an argument makes the seed as the time being, and generates different
random numbers.
def sample(n, m)
if m.zero?
[]
else
s = sample(n-1, m-1)
t = rand(n+1)
s.concat s.include?(t) ? n : t
end
end
To write it in non-recursive iterated form,
def sample(n, m)
s = []
((n-m)...n).each do |j|
t = rand(j+2)
s.concat s.include?(t) ? j+1 : t
end
s
end
Fixnum
, true
, nil
, and false
are implemented as immediate values, what is the difference between
an immediate value and a reference?
Fixnum
s of the same value are
always the same instance, so when instance variables are defined,
they point the same objects.
nil
and false
?
nil
and false
is
shown by executing nil.methods
- false.methods
and
false.methods
- nil.methods
.
nil
cannot be a value, but false
can.
true
or false
if it is a predicate, and a value or nil
otherwise.
?
is usually a predicate, but
some built-in functions are not.
open("example", "r+").readlines.each_with_index{|l, i|
l[0,0] = (i+1).to_s + ": "}
This script does not add line numbers to the file "example".
It is because this script does not write to the file but only change
the strings received from readlines
. You must write back the
result to the file.
io = open("example", "r+")
ary = io.readlines
ary.each_with_index{|l, i| l[0,0] = (i+1).to_s + ": "}
io.rewind
io.print ary
io.close
-i
, or built-in variable $-i
,
you can read a file and replace it.
$ ruby -i -ne 'print "#$.: #$_"' example
If you want to reserve the original file, use -i.bak
or
whatever you like.
open('file', 'w').print "This is a file.\n"
system 'cp file copy'
When copying the file
in this script, the content is not yet
flushed. You should close the file
before copying.
f = open('file', 'w')
f.print "This is a file.\n"
f.close
system "cp file copy"
less
to display strings?
f = open '|less', 'w'
f.print "abc\n"
This script ends immediately, and you cannot see less
displaying.
Use close
to wait until less
ends.
f = open '|less', 'w'
f.print "abc\n"
f.close
The first line can be written as f = IO.popen 'less', 'w'
.
File
object which has no reference?
File
object, which is not referred as in open("file").read
,
will be garbage collected in next GC, when it is closed.
(1)
a = open "file"
begin
a.each {|l| print l}
ensure
a.close
end
(2)
IO.foreach("file") {|l| print l}
(3)
IO.readlines("file").each {|l| print l}
Dir.glob("*").filter{|f| [File.mtime(f), f]}.
sort{|a,b| b[0]<=>a[0]}.filter{|e| e[1]}
This script returns an array with the filenames sorted by the
access time in reverse order. If you want to sort in straight order,
you can omit the block of sort.
Dir.glob("*").sort{|a,b| File.mtime(b)<=>File.mtime(a)}
will give the same answer, but this script takes longer time because
it accesses files each time it compares the modified time.
freq = Hash.new(0)
open("file").read.scan(/\w+/){|w| freq[w] += 1}
freq.keys.sort.each {|k| print k, "--", freq[k], "\n"}
true
in a condition expression.
nil
or false
returns false condition.
You can use empty?
or compare the string to "" or compare
length
to 0
to find out if a string is empty.
"abcd"[0]
return?
a
, do either of following.
1 while a.sub!(/(^[^\t]*)\t(\t*)/){$1+' '*(8-$1.size%8+8*$2.size)}
1 while a.sub!(/\t(\t*)/){' '*(8-$~.begin(0)%8+8*$1.size)}
a.gsub!(/([^\t]{8})|([^\t]*)\t/n){[$+].pack("A8")}
Regexp.quote('\\')
escapes a backslash.
gsub
, if you write gsub(/\\/, '\\\\')
, the second
argument is
analyzed as '\\' in syntax analysis and when the substitution occurs
it is again analyzed as '\' which means to substitute one backslash
to one backslash. You need to write gsub(/\\/, '\\\\\\')
. Using the
fact that \& expresses the match, you can write
gsub(/\\/, '\&\&')
.
gsub
, i.e. gsub(/\\/){'\\\\'}
,
the string for substitution is analyzed only once and the result is
what you intended.
sub
and sub!
?
sub
, a copy of the receiver is generated, substituted
and returned.
sub!
, the receiver is altered and returned if any match was
found. Otherwise, nil
is returned.
sub!
are called
destructive methods which alter the
attribute of the receiver. If there are two similar methods and one
is destructive, the destructive one has a suffix ! to denote the
destructiveness.
def foo(str)
str = str.sub(/foo/, "baz")
end
obj = "foo"
foo(obj)
print obj
# -> "foo"
def foo(str)
str = str.sub!(/foo/, "baz")
end
foo(obj)
print obj
# -> "baz"
Destructive methods like sub!
sometimes return an unexpected
result. Be careful.
..
and ...
?
..
includes the right hand side in the range, ...
does not.
Proc.new
, proc
, or lambda
serves as a function pointer.
thread
and fork
?
Thread
and fork
have following characteristics.
fork
is slow, thread
is not.fork
does not share the memory space.fork
,
thread
worse.thread
does not cause thrashing.thread
works on DOS.thread
gets in a deadlock, whole process stops.fork
and thread
.
thread
in Ruby is implemented by time sharing, dividing to
threads does not gain the speed of execution.
Marshal.dump obj, io, lev
io
is a writable IO object, lev
designate the level to which
referred objects are dereferred and stored. If lev levels of
dereferring are done and still object referrences exist, then
the dump of the object is only the referrence. It cannot be
reconstructed when loaded.
obj = Marshal.load io
or,
obj = Marshal.load str
io is a readable IO object, str is the dumped string.
begin
statements which may raise exceptions.
rescue [exception class name]
statements when an exception occurred.
ensure
statements to be done in the end.
end
If an exception occurs in the begin
clause, rescue
clause
is executed. The ensure
clause is executed whether an exception
occurred or not. rescue
and ensure
claused can be omitted.
If no exception class is designated for rescue
clause,
StandardError
exception is implied, and exceptions which are
in a is_a? relation to StandardError
are captured.
$!
.
The kind of exception is checked by $!.type
.
trap
?
trap("PIPE") {raise "SIGPIPE"}