tags:

views:

109

answers:

4

I have a class like:

class Configuration
  def self.files
    @@files ||= Array.new
  end
end

Now instead of doing this:

irb(main):001:0> Configuration.files
=> [file, file, file]

I would like to be able to do this:

irb(main):001:0> Configuration
=> [file, file, file]

But I can't figure out how, any ideas?


@glenn jackman:

I was thinking of adding extra methods to a 'Configuration' constant that's a hash. So if I had...

Configuration = Hash.new
Configuration[:foo] = 'bar'

I wanted to be able to save this Configuration hash constant to be able to dump to and load from a YAML file I wanted to be able to use...

Configuration.load
Configuration.save

I wanted the Configuration class to look like

class Configuration
  def self.save
    open('config.yml', 'w') {|f| YAML.dump( self , f)}
  end
  def self.load
    open('config.yml') {|f| YAML.load(f)}
  end
end
+6  A: 

You could possibly get the effect you are looking for by adding a method to the top level object which implicitly calls Configuration.files, but you can't really make a reference to a class invoke a method on it. You can alias the method to something shorter, but you will need to call something.

Kevin Peterson
+2  A: 

You could do something like this:

class Configuration
  (class << self; self; end).module_eval do
    def files
      ['foo','bar','baz']
    end
    def to_s
      files
    end
  end
end

This would define the Configuration.files method and say that the to string conversion would return the result of that method. But I am really not sure why you would want to do this. It seems quite wrong.

Rob Di Marco
A: 
wpc@wpc-laptop:~$ irb
irb(main):001:0> 'a'
=> a
irb(main):002:0> def A
irb(main):003:1> end
=> nil
irb(main):004:0> A
NameError: uninitialized constant A
    from (irb):4
    from :0
irb(main):005:0> class A
irb(main):006:1> end
=> nil
irb(main):007:0> A
=> A
irb(main):008:0> class A
irb(main):009:1> (class  ['g']
irb(main):012:3> end
irb(main):013:2> def to_s
irb(main):014:3> g
irb(main):015:3> end
irb(main):016:2> end
irb(main):017:1> end
=> nil
irb(main):018:0> A
=> g
irb(main):019:0> class B
irb(main):020:1> class  def to_s
irb(main):022:3> 'g'
irb(main):023:3> end
irb(main):024:2> end
irb(main):025:1> end
=> nil
irb(main):026:0> B
=> g
irb(main):027:0> class B
irb(main):028:1> class  def files
irb(main):030:3> ['a','b','c']
irb(main):031:3> end
irb(main):032:2> def to_s
irb(main):033:3> files
irb(main):034:3> end
irb(main):035:2> end
irb(main):036:1> end
=> nil
irb(main):037:0> B
=> abc

The right solution is to using the class' method of to_s, but what it return is only the string; and then you can set the inspect for using. See the follows' detail for help.

class A
  class<<self
    def to_s
      ......
    end
  end
end
Qianjigui
+3  A: 

irb's top level just calls 'inspect' on the result, so by overriding it you can customize what you see in irb:

$ irb
>> class Configuration
>>   def self.files
>>     @@files ||= Array.new
>>   end
>>   def self.inspect
>>     @@files.inspect
>>   end
>> end
=> nil
>> Configuration.files << 1 << 2 << 3
=> [1, 2, 3]
>> Configuration
=> [1, 2, 3]
Vitaly Kushner