Utility module to define eRuby script as instance method.
example.rhtml:
<% for item in @items %> <b><%= item %></b> <% end %>
example.rb:
require 'erb' class MyClass extend ERB::DefMethod def_erb_method('render()', 'example.rhtml') def initialize(items) @items = items end end print MyClass.new([10,20,30]).render()
result:
<b>10</b> <b>20</b> <b>30</b>
HTTPAuth
provides both basic and digest authentication.
To enable authentication for requests in WEBrick
you will need a user database and an authenticator. To start, here’s an Htpasswd
database for use with a DigestAuth
authenticator:
config = { :Realm => 'DigestAuth example realm' } htpasswd = WEBrick::HTTPAuth::Htpasswd.new 'my_password_file' htpasswd.auth_type = WEBrick::HTTPAuth::DigestAuth htpasswd.set_passwd config[:Realm], 'username', 'password' htpasswd.flush
The :Realm
is used to provide different access to different groups across several resources on a server. Typically you’ll need only one realm for a server.
This database can be used to create an authenticator:
config[:UserDB] = htpasswd digest_auth = WEBrick::HTTPAuth::DigestAuth.new config
To authenticate a request call authenticate with a request and response object in a servlet:
def do_GET req, res @authenticator.authenticate req, res end
For digest authentication the authenticator must not be created every request, it must be passed in as an option via WEBrick::HTTPServer#mount
.
Numeric
is the class from which all higher-level numeric classes should inherit.
Numeric
allows instantiation of heap-allocated objects. Other core numeric classes such as Integer
are implemented as immediates, which means that each Integer
is a single immutable object which is always passed by value.
a = 1 1.object_id == a.object_id #=> true
There can only ever be one instance of the integer 1
, for example. Ruby ensures this by preventing instantiation. If duplication is attempted, the same instance is returned.
Integer.new(1) #=> NoMethodError: undefined method `new' for Integer:Class 1.dup #=> 1 1.object_id == 1.dup.object_id #=> true
For this reason, Numeric
should be used when defining other numeric classes.
Classes which inherit from Numeric
must implement coerce
, which returns a two-member Array
containing an object that has been coerced into an instance of the new class and self
(see coerce
).
Inheriting classes should also implement arithmetic operator methods (+
, -
, *
and /
) and the <=>
operator (see Comparable
). These methods may rely on coerce
to ensure interoperability with instances of other numeric classes.
class Tally < Numeric def initialize(string) @string = string end def to_s @string end def to_i @string.size end def coerce(other) [self.class.new('|' * other.to_i), self] end def <=>(other) to_i <=> other.to_i end def +(other) self.class.new('|' * (to_i + other.to_i)) end def -(other) self.class.new('|' * (to_i - other.to_i)) end def *(other) self.class.new('|' * (to_i * other.to_i)) end def /(other) self.class.new('|' * (to_i / other.to_i)) end end tally = Tally.new('||') puts tally * 2 #=> "||||" puts tally > 1 #=> true
Float
objects represent inexact real numbers using the native architecture’s double-precision floating point representation.
Floating point has a different arithmetic and is an inexact number. So you should know its esoteric system. See following:
Continuation
objects are generated by Kernel#callcc
, after having +require+d continuation. They hold a return address and execution context, allowing a nonlocal return to the end of the callcc
block from anywhere within a program. Continuations are somewhat analogous to a structured version of C’s setjmp/longjmp
(although they contain more state, so you might consider them closer to threads).
For instance:
require "continuation" arr = [ "Freddie", "Herbie", "Ron", "Max", "Ringo" ] callcc{|cc| $cc = cc} puts(message = arr.shift) $cc.call unless message =~ /Max/
produces:
Freddie Herbie Ron Max
Also you can call callcc in other methods:
require "continuation" def g arr = [ "Freddie", "Herbie", "Ron", "Max", "Ringo" ] cc = callcc { |cc| cc } puts arr.shift return cc, arr.size end def f c, size = g c.call(c) if size > 1 end f
This (somewhat contrived) example allows the inner loop to abandon processing early:
require "continuation" callcc {|cont| for i in 0..4 print "\n#{i}: " for j in i*5...(i+1)*5 cont.call() if j == 17 printf "%3d", j end end } puts
produces:
0: 0 1 2 3 4 1: 5 6 7 8 9 2: 10 11 12 13 14 3: 15 16
Raised to stop the iteration, in particular by Enumerator#next
. It is rescued by Kernel#loop
.
loop do puts "Hello" raise StopIteration puts "World" end puts "Done!"
produces:
Hello Done!
Raised by exit
to initiate the termination of the script.
fatal is an Exception
that is raised when Ruby has encountered a fatal error and must exit. You are not able to rescue fatal.
Raised when a signal is received.
begin Process.kill('HUP',Process.pid) sleep # wait for receiver to handle signal sent by Process.kill rescue SignalException => e puts "received Exception #{e}" end
produces:
received Exception SIGHUP
Raised when the arguments are wrong and there isn’t a more specific Exception
class.
Ex: passing the wrong number of arguments
[1, 2, 3].first(4, 5)
raises the exception:
ArgumentError: wrong number of arguments (given 2, expected 1)
Ex: passing an argument that is not acceptable:
[1, 2, 3].first(-4)
raises the exception:
ArgumentError: negative array size
Raised when a feature is not implemented on the current platform. For example, methods depending on the fsync
or fork
system calls may raise this exception if the underlying operating system or Ruby runtime does not support them.
Note that if fork
raises a NotImplementedError
, then respond_to?(:fork)
returns false
.
A generic error class raised when an invalid operation is attempted. Kernel#raise
will raise a RuntimeError
if no Exception
class is specified.
raise "ouch"
raises the exception:
RuntimeError: ouch
Raised when memory allocation fails.
date and datetime class - Tadayoshi Funaba 1998-2011
‘date’ provides two classes: Date
and DateTime
.
Some terms and definitions are based on ISO 8601 and JIS X 0301.
Date
The calendar date is a particular day of a calendar year, identified by its ordinal number within a calendar month within that year.
In those classes, this is so-called “civil”.
Date
The ordinal date is a particular day of a calendar year identified by its ordinal number within the year.
In those classes, this is so-called “ordinal”.
Date
The week date is a date identified by calendar week and day numbers.
The calendar week is a seven day period within a calendar year, starting on a Monday and identified by its ordinal number within the year; the first calendar week of the year is the one that includes the first Thursday of that year. In the Gregorian calendar, this is equivalent to the week which includes January 4.
In those classes, this is so-called “commercial”.
The Julian day number is in elapsed days since noon (Greenwich Mean Time
) on January 1, 4713 BCE (in the Julian calendar).
In this document, the astronomical Julian day number is the same as the original Julian day number. And the chronological Julian day number is a variation of the Julian day number. Its days begin at midnight on local time.
In this document, when the term “Julian day number” simply appears, it just refers to “chronological Julian day number”, not the original.
In those classes, those are so-called “ajd” and “jd”.
The modified Julian day number is in elapsed days since midnight (Coordinated Universal Time
) on November 17, 1858 CE (in the Gregorian calendar).
In this document, the astronomical modified Julian day number is the same as the original modified Julian day number. And the chronological modified Julian day number is a variation of the modified Julian day number. Its days begin at midnight on local time.
In this document, when the term “modified Julian day number” simply appears, it just refers to “chronological modified Julian day number”, not the original.
In those classes, those are so-called “amjd” and “mjd”.
Date
A subclass of Object
that includes the Comparable
module and easily handles date.
A Date
object is created with Date::new
, Date::jd
, Date::ordinal
, Date::commercial
, Date::parse
, Date::strptime
, Date::today
, Time#to_date
, etc.
require 'date' Date.new(2001,2,3) #=> #<Date: 2001-02-03 ...> Date.jd(2451944) #=> #<Date: 2001-02-03 ...> Date.ordinal(2001,34) #=> #<Date: 2001-02-03 ...> Date.commercial(2001,5,6) #=> #<Date: 2001-02-03 ...> Date.parse('2001-02-03') #=> #<Date: 2001-02-03 ...> Date.strptime('03-02-2001', '%d-%m-%Y') #=> #<Date: 2001-02-03 ...> Time.new(2001,2,3).to_date #=> #<Date: 2001-02-03 ...>
All date objects are immutable; hence cannot modify themselves.
The concept of a date object can be represented as a tuple of the day count, the offset and the day of calendar reform.
The day count denotes the absolute position of a temporal dimension. The offset is relative adjustment, which determines decoded local time with the day count. The day of calendar reform denotes the start day of the new style. The old style of the West is the Julian calendar which was adopted by Caesar. The new style is the Gregorian calendar, which is the current civil calendar of many countries.
The day count is virtually the astronomical Julian day number. The offset in this class is usually zero, and cannot be specified directly.
A Date
object can be created with an optional argument, the day of calendar reform as a Julian day number, which should be 2298874 to 2426355 or negative/positive infinity. The default value is Date::ITALY
(2299161=1582-10-15). See also sample/cal.rb.
$ ruby sample/cal.rb -c it 10 1582 October 1582 S M Tu W Th F S 1 2 3 4 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 $ ruby sample/cal.rb -c gb 9 1752 September 1752 S M Tu W Th F S 1 2 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
A Date
object has various methods. See each reference.
d = Date.parse('3rd Feb 2001') #=> #<Date: 2001-02-03 ...> d.year #=> 2001 d.mon #=> 2 d.mday #=> 3 d.wday #=> 6 d += 1 #=> #<Date: 2001-02-04 ...> d.strftime('%a %d %b %Y') #=> "Sun 04 Feb 2001"
Time
is an abstraction of dates and times. Time
is stored internally as the number of seconds with fraction since the Epoch, January 1, 1970 00:00 UTC. Also see the library module Date
. The Time
class treats GMT (Greenwich Mean Time
) and UTC (Coordinated Universal Time
) as equivalent. GMT is the older way of referring to these baseline times but persists in the names of calls on POSIX systems.
All times may have fraction. Be aware of this fact when comparing times with each other – times that are apparently equal when displayed may be different when compared.
Since Ruby 1.9.2, Time
implementation uses a signed 63 bit integer, Bignum or Rational
. The integer is a number of nanoseconds since the Epoch which can represent 1823-11-12 to 2116-02-20. When Bignum or Rational
is used (before 1823, after 2116, under nanosecond), Time
works slower as when integer is used.
All of these examples were done using the EST timezone which is GMT-5.
Time
instance You can create a new instance of Time
with Time::new
. This will use the current system time. Time::now
is an alias for this. You can also pass parts of the time to Time::new
such as year, month, minute, etc. When you want to construct a time this way you must pass at least a year. If you pass the year with nothing else time will default to January 1 of that year at 00:00:00 with the current system timezone. Here are some examples:
Time.new(2002) #=> 2002-01-01 00:00:00 -0500 Time.new(2002, 10) #=> 2002-10-01 00:00:00 -0500 Time.new(2002, 10, 31) #=> 2002-10-31 00:00:00 -0500
You can pass a UTC offset:
Time.new(2002, 10, 31, 2, 2, 2, "+02:00") #=> 2002-10-31 02:02:02 +0200
Or a timezone object:
tz = timezone("Europe/Athens") # Eastern European Time, UTC+2 Time.new(2002, 10, 31, 2, 2, 2, tz) #=> 2002-10-31 02:02:02 +0200
You can also use Time::gm
, Time::local
and Time::utc
to infer GMT, local and UTC timezones instead of using the current system setting.
You can also create a new time using Time::at
which takes the number of seconds (or fraction of seconds) since the Unix Epoch.
Time.at(628232400) #=> 1989-11-28 00:00:00 -0500
Time
Once you have an instance of Time
there is a multitude of things you can do with it. Below are some examples. For all of the following examples, we will work on the assumption that you have done the following:
t = Time.new(1993, 02, 24, 12, 0, 0, "+09:00")
Was that a monday?
t.monday? #=> false
What year was that again?
t.year #=> 1993
Was it daylight savings at the time?
t.dst? #=> false
What’s the day a year later?
t + (60*60*24*365) #=> 1994-02-24 12:00:00 +0900
How many seconds was that since the Unix Epoch?
t.to_i #=> 730522800
You can also do standard functions like compare two times.
t1 = Time.new(2010) t2 = Time.new(2011) t1 == t2 #=> false t1 == t1 #=> true t1 < t2 #=> true t1 > t2 #=> false Time.new(2010,10,31).between?(t1, t2) #=> true
A timezone argument must have local_to_utc
and utc_to_local
methods, and may have name
and abbr
methods.
The local_to_utc
method should convert a Time-like object from the timezone to UTC, and utc_to_local
is the opposite. The result also should be a Time
or Time-like object (not necessary to be the same class). The zone
of the result is just ignored. Time-like argument to these methods is similar to a Time
object in UTC without sub-second; it has attribute readers for the parts, e.g. year
, month
, and so on, and epoch time readers, to_i
. The sub-second attributes are fixed as 0, and utc_offset
, zone
, isdst
, and their aliases are same as a Time
object in UTC. Also to_time
, +
, and -
methods are defined.
The name
method is used for marshaling. If this method is not defined on a timezone object, Time
objects using that timezone object can not be dumped by Marshal
.
The abbr
method is used by ‘%Z’ in strftime
.
At loading marshaled data, a timezone name will be converted to a timezone object by find_timezone
class method, if the method is defined.
Similary, that class method will be called when a timezone argument does not have the necessary methods mentioned above.
Raised when OLE processing failed.
EX:
obj = WIN32OLE.new("NonExistProgID")
raises the exception:
WIN32OLERuntimeError: unknown OLE server: `NonExistProgID' HRESULT error code:0x800401f3 Invalid class string
This library provides three different ways to delegate method calls to an object. The easiest to use is SimpleDelegator
. Pass an object to the constructor and all methods supported by the object will be delegated. This object can be changed later.
Going a step further, the top level DelegateClass method allows you to easily setup delegation through class inheritance. This is considerably more flexible and thus probably the most common use for this library.
Finally, if you need full control over the delegation scheme, you can inherit from the abstract class Delegator
and customize as needed. (If you find yourself needing this control, have a look at Forwardable which is also in the standard library. It may suit your needs better.)
SimpleDelegator’s implementation serves as a nice example of the use of Delegator:
class SimpleDelegator < Delegator def __getobj__ @delegate_sd_obj # return object we are delegating to, required end def __setobj__(obj) @delegate_sd_obj = obj # change delegation object, # a feature we're providing end end
Be advised, RDoc
will not detect delegated methods.
A concrete implementation of Delegator
, this class provides the means to delegate all supported method calls to the object passed into the constructor and even to change the object being delegated to at a later time with __setobj__
.
class User def born_on Date.new(1989, 9, 10) end end class UserDecorator < SimpleDelegator def birth_year born_on.year end end decorated_user = UserDecorator.new(User.new) decorated_user.birth_year #=> 1989 decorated_user.__getobj__ #=> #<User: ...>
A SimpleDelegator
instance can take advantage of the fact that SimpleDelegator
is a subclass of Delegator
to call super
to have methods called on the object being delegated to.
class SuperArray < SimpleDelegator def [](*args) super + 1 end end SuperArray.new([1])[0] #=> 2
Here’s a simple example that takes advantage of the fact that SimpleDelegator’s delegation object can be changed at any time.
class Stats def initialize @source = SimpleDelegator.new([]) end def stats(records) @source.__setobj__(records) "Elements: #{@source.size}\n" + " Non-Nil: #{@source.compact.size}\n" + " Unique: #{@source.uniq.size}\n" end end s = Stats.new puts s.stats(%w{James Edward Gray II}) puts puts s.stats([1, 2, 3, nil, 4, 5, 1, 2])
Prints:
Elements: 4 Non-Nil: 4 Unique: 4 Elements: 8 Non-Nil: 7 Unique: 6
IPAddr
provides a set of methods to manipulate an IP address. Both IPv4 and IPv6 are supported.
require 'ipaddr' ipaddr1 = IPAddr.new "3ffe:505:2::1" p ipaddr1 #=> #<IPAddr: IPv6:3ffe:0505:0002:0000:0000:0000:0000:0001/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff> p ipaddr1.to_s #=> "3ffe:505:2::1" ipaddr2 = ipaddr1.mask(48) #=> #<IPAddr: IPv6:3ffe:0505:0002:0000:0000:0000:0000:0000/ffff:ffff:ffff:0000:0000:0000:0000:0000> p ipaddr2.to_s #=> "3ffe:505:2::" ipaddr3 = IPAddr.new "192.168.2.0/24" p ipaddr3 #=> #<IPAddr: IPv4:192.168.2.0/255.255.255.0>