1

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
3
  • To clarify, you want a class to return a value like a method? Commented Aug 18, 2009 at 3:14
  • Pretty much, yeah. I'm just gonna redesign the whole application with modules instead of classes. Thanks though, guys. Commented Aug 18, 2009 at 3:44
  • So, if you do 'myfiles = Configuration', you want myfiles to refer to an array of files and not the Configuration class? Are you sure you have the right design? Commented Aug 19, 2009 at 13:31

4 Answers 4

6

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.

Sign up to request clarification or add additional context in comments.

Comments

3

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]

Comments

2

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.

Comments

0
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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.