Well, my code does seem to work, but I have the feeling that I could
have
done it much simpler… So here is my problem:
I would like to control log4r via an environment variable, which can
contain one of 4 types of values:
stdout : logging goes to stdout
stderr : logging goes to stderr
file:FILENAME : logging goes to FILENAME
none : logging not needed
The problem is what outputter to use to implement ‘none’. My first idea
to simply use FileOutputter(‘none’,:filename => ‘/dev/null’) does not
work
because my code is also supposed to run onder Windows where we don’t
have
/dev/null. So I came up with the solution to invent a “NullOutputter”:
class NullOutputter <Outputter
def initialize(name)
super(name)
end
end
…
$log = Logger.new(‘TestLog’)
outputterspec=ENV[‘TFW_LOG’] || ‘stdout’
$log.outputters = case outputterspec
when ‘stdout’
Outputter.stdout
when ‘stderr’
Outputter.stderr
when /^file:(.+)$/
FileOutputter.new ‘tfw’, :filename => $1, :trunc => true
when ‘none’
NullOutputter.new ‘tfwnull’
end
Note that I did NOT use
when ‘none’
Outputter.new ‘tfwnull’
because Outputter is documented as abstract class.
My solution works, but I wonder whether I could make it simpler
(i.e. without creating the NullOutputter class).
Ronald
On 7/17/07, Ronald F. [email protected] wrote:
The problem is what outputter to use to implement ‘none’. My first idea
to simply use FileOutputter(‘none’,:filename => ‘/dev/null’) does not
work
because my code is also supposed to run onder Windows where we don’t
have
/dev/null.
There is a /dev/null equivalent on Windows, NUL: You can use it in
this fashion …
fn = test(?e, ‘/dev/null’) ? ‘/dev/null’ : ‘NUL:’
fd = File.open(fn, ‘w’)
You can now write to that file descriptor and everything will go to
the bit bucket.
My solution works, but I wonder whether I could make it simpler
(i.e. without creating the NullOutputter class).
Certainly. Just create an instance of Outputter and then define the
methods you need.
out = Outputter.new ‘tfwnull’
class << out
def canonical_log(logevent) nil end
end
The canonical_log method is used by the outputters to format the log
event and then write the formatted output to a file. By setting this
to have a nil body, you will save a few cycles each time a log
messages needs to be generated.
Another options is just to set the global log level to ‘off’. That is
left as an exercise for the reader 
Blessings,
TwP
end
Now I wonder, since Outputter is documented as abstract class, why
I can instantiate it at all? Or is “abstract class” in Ruby not dealt
with the same strength as in, say, Java or C++?
But anyway, I tried your approach, but I don’t see how I get the
instance
of the anonymous class into my outputters. When I do it like this:
#!/usr/bin/ruby
require ‘log4r’
include Log4r
$log=Logger.new(‘testing’)
out = Outputter.new ‘tfwnull’
$log.outputters=class << out
def canonical_log(logevent) nil end
end
I get the error message
“Expected kind of Outputter, got NilClass (TypeError)”
Ronald