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