--00163630f5f3e1c80b049a1e2a57
Content-Type: text/plain; charset=ISO-8859-1

On Sun, Jan 16, 2011 at 7:59 AM, Josh Cheek <josh.cheek / gmail.com> wrote:

> My questions are:
> 1. Is any other situation where this information is relevant?
>

I found one more situation where this knowledge is relevant.

When you are in your main object, and you define methods (here, they feel
like functions), they become available to all objects. The reason for this
is because the current class is set to Object, so defining methods in main
defines them as instance methods of Object, which is an ancestor of most
classes, so most objects can now invoke this method.

To test this, I went to Ruby 1.9, which has BasicObject that does not
inherit from Object, and showed that you can invoke f from an instance of
Object, but not an instance of BasicObject.



RUBY_VERSION # "1.9.1"

# create a new function in the main object
self                      # main
defined? f                # nil
def f
  'you see f'
end


# current class is Object, so it defines the method on object
method :f                 # #<Method: Object#f>
Object.instance_method :f # #<UnboundMethod: Object#f>


# Object inherits from BasicObject
# BasicObject inherits from nothing
Object.ancestors          # [Object, Kernel, BasicObject]
BasicObject.ancestors     # [BasicObject]


# so if f exists on instances of Object,
# but not instances of BasicObject,
# then the explanation of top-level "functions" is that
# current class is Object, so def keyword defines methods in Object
# and almost everything inherits from Object, so it is visible everywhere
Array.new.instance_eval { f } # "you see f"
begin
  BasicObject.new.instance_eval { f } # rescue
  $!.to_s # "undefined local variable or method `f' for
#<BasicObject:0x428a80>"
end


# But the main object must be declared privately,
# to which prevent it from showing up in objects' methods lists
# or being able to do stupid things like this
begin
  Array.new.f    # rescue
  $!.to_s # "private method `f' called for []:Array"
end


# to test this, the above code should work if we make f public
public :f
Array.new.f # "you see f"

--00163630f5f3e1c80b049a1e2a57--