From: Ross Bamford Date: 2006-03-01T22:29:17+09:00 Subject: Re: Dynamic stuff and books On Wed, 2006-03-01 at 21:48 +0900, Mc Osten wrote: > On Tue, 28 Feb 2006 22:03:04 +0900, Ross Bamford wrote: > > Not quite. You're actually evaluating it in the context of an instance > > of Class, that being the singleton class for 'something'. > > So not in the something context, but in a "subclass without name" (the > singleton class). Ok. > > So everytime I'm doing something with << and classes I'm working with > subclasses? > In terms of the implementation, it would seem so (thanks, Logan), and indeed it makes sense in your code too: str = "one" # => "one" class << str def gsub(*args, &blk) super(*args, &blk) end end # => nil str.gsub(/o/,'O') # => "One" > > Mostly that's true, but there is at least one difference to keep in mind > > - multiple class SomeClass ... definitions will 'reopen' the existing > > class and allow new methods to be added: > > Yes. That's true. I didn't think about it. It's one of the things I really > love, indeed. But... > > Is there anyway to "reopen" a class with the "raw" syntax? > > Something.reopen do > # code... > end > In a way, yes: class Something def a; 'a'; end end # => nil Something.class_eval do def b; 'b'; end end # => nil Something.new.a # => "a" Something.new.b # => "b" > > And no, no-one is going to get upset about it (well, no-one who does > > Ruby anyway). I consider this kind of metaprogrammability to be one of > > Ruby's sleekest features. Whether your boss, or your customer, or > > whoever else, gets upset about it depends on too many external factors > > to predict :) > > This is not an issue... it was just a matter of "style". I come from > Python, there are lots of things that are perfectly legal, but are felt > "unpythonic" and thus better avoided (I'm not speaking of metaprogramming, > but of "bad style"). > I was asking if the "good Ruby programmer" was "allowed" to hack in this > sense even in production or if it was considered just an "intellectual > exercise" (as are obfuscated C/Perl contexts). > I don't consider metaprogramming bad style, and I think it's a fairly well-used practice over here. It is potentially very dangerous, and can easily be misused (and overused) with really hard-to-debug results, but just as a butcher works better with sharp knives, sometimes so do we. Generally I'd advise metaprogramming be used only when no other 'standard' technique can do the job, or would be so inelegant as to be pointless. > > Top-level 'functions' are private methods on Object (I was sure it was > > Kernel but it doesn't appear so): > > Ok. In fact it told me I was calling a private method, but I did not > understand why. It's meant that way. > > > Since they're private, and on Object, you get the expected behaviour > > that you can only call them with no receiver, and from anywhere. > > May I ask why? Because they're defined on Object, they are available everywhere (in the context of any 'self'). And because they're private, they can only be called with the implicit 'self', so they act like functions. You can use 'send' to call them, of course, which demonstrates the point: def one p self end one # => main # This line would raise a private method error #"hey".one "hey".send(:one) # => "hey" 88.send(:one) # => 88 ('main' is just an Object corresponding to the top-level scope). -- Ross Bamford - rosco@roscopeco.REMOVE.co.uk