From: Robert Klemme Date: 2011-03-28T05:15:26+09:00 Subject: Re: Dynamic classes On 26.03.2011 19:16, Vicente Bosch Campos wrote: > >> On 26.03.2011 15:38, Vicente Bosch Campos wrote: >>> and I should be able to change its properties and that should be >>> independent of having the definition assigned to a variable >>> otherwise it would be discarded as you say. >> >> You can change a class's properties, e.g. by adding methods etc. >> It's just that the name happens to be a read only property and >> there is some additional magic which will set it on first constant >> assignment. I don't see how that collides with a "purist >> perspective". > > I have not explained my self properly. Imagine we are talking about > making an instance of any other object e.g. a Car and the car has a > name and it allows you reference the car instance by it in the > future. > > Would you prefer the car name is defined by the variable that > contains it or by setting the name in the constructor? > > hotwheels = Car.new > > current_car = Car.new("hotwheels") > > I don't think anyone would understand directly that I have > automatically set a property inside my car with the variable name. It > would be a bit counterintuitive and different from how any other > instance properties work on this class and how they are usually set > on any other type of object of any library. > > Considering the Class to be an object too by not allowing me set the > name at the .new and taking the name of the left hand side of the > equality sign in case it is a Constant ( otherwise it does not) it is > not acting very much like any other object. OK, now I get your point. Thanks! I think Matz just decides that doing X = Class.new do def foo; end end is less clean than class X def foo; end end and hence created the const magic because class definitions are so common. If you want, you can still use the bar bones idiom though. >> The approach with Object.const_set basically only makes sense if >> the name is dynamic, too. > > Yes sorry, I do want to have the name dynamic too ( I might be going > off-topic for the original post, sorry). Then consider this: if the name is dynamic during definition it certainly has to be dynamic during referencing as well. In that case there is probably not much point in assigning the class to a constant. Rather a Hash would be a much better place to keep all those classes around. You could even do something like this: irb(main):012:0> cl = Hash.new do |h,name| irb(main):013:1* c = Class.new irb(main):014:1> class< h[name]=c irb(main):016:1> end => {} irb(main):017:0> cl["Foo"] => # irb(main):018:0> cl["Foo"] => # irb(main):019:0> cl["Foo"].name => "Foo" or irb(main):027:0> cl = {} => {} irb(main):028:0> def cl.new_class(name, &b) irb(main):029:1> c = Class.new(&b) irb(main):030:1> class< self[name]=c irb(main):032:1> end => nil irb(main):033:0> cl.new_class "Foo" do irb(main):034:1* def bar;123;end irb(main):035:1> end => # irb(main):036:0> cl["Foo"] => # irb(main):037:0> cl["Foo"] => # irb(main):038:0> cl["Foo"].name => "Foo" irb(main):039:0> cl["Foo"].new.bar => 123 Now the Hash defines a namespace where all your dynamic classes reside. If you want to get rid of them you just need to clear the Hash. This approach can be extended to define a specific DSL for your domain which would make method definitions even simpler. > I am just saying it would be nicer to do Class.new("Bar") would be > much more like any other object instantiation and less questioned > about as it would not be an exception to how the rest of the stuff > works ( although Class object is truly a bit of an exception and its > one of those marvelous things ruby allows us to tinker with ). Actually I haven't seen the syntax "class Name ... end" questioned in a while. I believe this is such a fundamental and frequent idiom to warrant a bit of syntactic sugar mixed with naming magic. :-) > Many thanks for the healthy discussion :-) Ditto. Kind regards robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/