From: Brian Candler Date: 2012-11-11T18:31:25+09:00 Subject: Re: Instance name of a class/object? Carolyn Grant wrote in post #1083906: > basic_config = MySettings.new # Picks up & processes basic_config.yml > adv_config = MySettings.new # Picks up & processes adv_config.yml In general it doesn't make any sense for an object to know its "name", because an object may have zero or many names at any time. You can assign the object reference to local variables, to global variables, to instance variables of other objects, to constants, as elements of an Array or Hash, etc. In the above code, the object created by MySettings.new has no name at the time it is created. Only after the #new function has returned the object reference, it is assigned to the local variable. So for the code you are writing above, I would strongly advise passing the filename (or filename stem) as an argument: basic_config = MySettings.new("basic_config.yaml") adv_config = MySettings.new("adv_config.yaml") Of course, as with many things in Ruby, there is an exception. The exception is to do with class objects; that is, objects of class Class. Normally classes are held in constants, and the first time a class is assigned to a constant, it learns its name, and the name becomes an attribute of the class itself. A class definition like "class Foo" both creates the class and assigns it to a constant, but you can see the behaviour if you first create an anonymous class, and then later assign it to a constant. >> foo = Class.new => # >> my_instance = foo.new => #<#:0x106c8e6f8> >> Bar = foo => Bar >> foo => Bar >> my_instance => # >> Baz = foo => Bar >> foo => Bar >> my_instance => # > I tried my_class.name; that returns a "Method not defined" error" (I'm > using 1.9.3p194) You'll have to show the code. I use ruby 1.8, but it works fine for me. Notice that "name" is a method of the class, not the instance, and is only for Class objects because of the special-case behaviour described above. >> foo.name => "Bar" >> my_instance.class.name => "Bar" >> my_instance.name NoMethodError: undefined method `name' for # from (irb):11 > What I'd really like to avoid is: > > basic_config = MySettings.new(basic_config). Why? It seems you want to create "magic" which will be very difficult for another programmer to follow. When you create an object, you should pass all the data which will be used to create state in that object, and you should allow the caller to decide what to do with the returned object. The closest I could recommend is if you have a single config object which holds all the sub-configs e.g. a hash. Then a single method argument can say which file to load *and* which hash member to put it in. For example: require 'yaml' class Configs def initialize @configs = {} end def load(stem) @configs[stem] = File.open("#{stem}.yaml") do |f| YAML.load(f) end end def [](stem) @configs[stem] end end config = Configs.new config.load "basic_config" config.load "adv_config" puts config["basic_config"].inspect Of course, if you want the config to be globally accessible throughout your application, then you can assign it to a constant instead of a local variable. Config = Configs.new Config.load "basic_config" Config.load "adv_config" puts Config["basic_config"].inspect Or you could use a global variable, but a constant is generally preferred. Constants can be put into namespaces, e.g. MyApp::Config, to avoid clashes with other uses of Config. -- Posted via http://www.ruby-forum.com/.