# Problem with Ruby scoping rules?

**URL:** <https://www.ruby-forum.com/t/problem-with-ruby-scoping-rules/58727>\
**Category:** Ruby\
**Created:** [April 25, 2006, 11:12am UTC](https://www.ruby-forum.com/t/problem-with-ruby-scoping-rules/58727 "2006-04-25T11:12:28Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![Ed\_Syrett](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/a587f6/32.png) [@Ed\_Syrett](https://www.ruby-forum.com/u/Ed_Syrett)\
**Post date:** [April 25, 2006, 11:12am UTC](https://www.ruby-forum.com/t/problem-with-ruby-scoping-rules/58727/1 "2006-04-25T11:12:28Z")

</div>

I’ve been using Log4r with a Rails app for some time, and it was working  
fine under Webrick. Adding Log4r was easy - simply add in the following  
code to environment.rb:

# See Rails::Configuration for more options

begin  
cfg = Log4r::Configurator  
cfg[‘RAILS\_ROOT’] = RAILS\_ROOT  
cfg[‘RAILS\_ENV’] = RAILS\_ENV  
cfg.load\_xml\_file(File.dirname( **FILE** ) +  
“/…/public/config/BlackTestLog.xml”)  
RAILS\_DEFAULT\_LOGGER = Log4r::Logger[‘default’]  
RAILS\_DEFAULT\_LOGGER.info(“Initialised Log4r default logger”)  
rescue =\> err  
RAILS\_DEFAULT\_LOGGER = Logger.new(File.dirname( **FILE** ) +  
“/…/log/configuration\_error.log”)  
RAILS\_DEFAULT\_LOGGER.level = Logger::WARN  
RAILS\_DEFAULT\_LOGGER.warn(“Error occurred whilst initialising  
Log4r:”)  
RAILS\_DEFAULT\_LOGGER.warn(err.to\_s)  
RAILS\_DEFAULT\_LOGGER.warn(err.backtrace)  
end

However, I started running the Rails app under Apache. Everything  
worked fine except that load\_xml\_file always failed and I ended up using  
the default Rails logger.

To understand where I went next, you have to have a look at  
configurator.rb in Log4r. In there is the following method:

```
def self.decode_logger_common(l, e)

  ...stuff...

  # and now for outputters
  outs = e.value_of 'outputters'

  ## The add method........................v
  Log4rTools.comma_split(outs).each {|n| l.add n.strip} unless 

```

outs.nil?

```
  e.elements.each('outputter') {|e|
    name = (e.value_of 'name' or e.text)
    l.add Outputter[name]
  }
end

```

What I observed happening got me very worried. The l parameter is  
supposed to be an object of class Log4r::Logger, yet the call to add  
(marked above) ended up running the add method on the Rails default  
logger.

I made a change in decode\_logger to make sure that the object created  
was definitely a Log4r::Logger.

```
def self.decode_logger(e)
  l = Log4r::Logger.new e.value_of('name')
  decode_logger_common(l, e)
end

```

I then dumped l.inspect and here’s what it showed:

#\<Log4r::Logger:0x3618ae8 @progname=nil, @level=0, @formatter=nil,  
@logdev=#\<Log4r::Logger::LogDevice:0x3618620 @shift\_size=1048576,  
@shift\_age=0, @dev=#\<File:default\>, @filename=“default”,  
@mutex=#\<Log4r::Logger::LogDevice::LogDeviceMutex:0x36185f0  
@mon\_waiting\_queue=[], @mon\_entering\_queue=[], @mon\_count=0,  
@mon\_owner=nil\>\>,  
@default\_formatter=#\<Log4r::Logger::Formatter:0x36188d8  
@datetime\_format=nil\>\>

Now this is very worrying. Firstly the created object purports to be a  
Log4r::Logger, but unfortunately it has the attributes of the default  
Rails Logger. For example, Log4r::Logger doesn’t have @logdev.

From any perspective, this behaviour is plain wrong. I have asked Ruby  
to create a Logger object and scoped it within the Log4r namespace.  
However, it has created some other Logger object and pretended that it  
is the Log4r implementation. If Ruby cannot find the Log4r::Logger  
object for any reason, it should throw an error, not go and create the  
next best thing behind the scenes.

I’m therefore of the opinion that there is a problem with the Ruby  
interpreter in the way it handles scoping. Just the results of  
l.inspect above indicate there is a problem as the object has the name  
of the Log4r::Logger, but has been initialised as the Rails default  
Logger.

Any help with understanding what’s going on here would be welcome.

BTW I’ve now got a workaround for this problem but I don’t yet know why  
it works.
