How to call a class method via the singleton if it exists

I want to call a class level method from the the instance level, but I
need it to go through the singeton if it exists. Here is the most basic
example:

  class X
    def self.f ; "A" ; end
    def g ; self.class.f ; end
  end

  x = X.new
  x.g #=> "A"

  def x.f; "B"; end
  x.g #=> "A"

How do I get the last to return "B"? I know I could use
'(class<<self;self;end)' instead of 'self.class', but that will create
a singelton even if doesn't exist, which seems very wasteful. Yet I
don't recall any (non-hack) way to detect if a singleton is defined. Is
there?

It would be nice if there was a reference with which we could call up
through the class level like this.

T.

Two ideas attached.

  robert

dispatch.rb (636 Bytes)

···

On 18.11.2006 16:56, Trans wrote:

I want to call a class level method from the the instance level, but I
need it to go through the singeton if it exists. Here is the most basic
example:

  class X
    def self.f ; "A" ; end
    def g ; self.class.f ; end
  end

  x = X.new
  x.g #=> "A"

  def x.f; "B"; end
  x.g #=> "A"

How do I get the last to return "B"? I know I could use
'(class<<self;self;end)' instead of 'self.class', but that will create
a singelton even if doesn't exist, which seems very wasteful. Yet I
don't recall any (non-hack) way to detect if a singleton is defined. Is
there?

It would be nice if there was a reference with which we could call up
through the class level like this.

Hi,

At Sun, 19 Nov 2006 01:00:15 +0900,
Trans wrote in [ruby-talk:225642]:

I want to call a class level method from the the instance level, but I
need it to go through the singeton if it exists. Here is the most basic
example:

If I were you:

  class X
    def self.f ; "A" ; end

      def f; self.class.f; end
      def g ; f ; end

···

  end

--
Nobu Nakada

Robert Klemme wrote:

> I want to call a class level method from the the instance level, but I
> need it to go through the singeton if it exists. Here is the most basic
> example:
>
> class X
> def self.f ; "A" ; end
> def g ; self.class.f ; end
> end
>
> x = X.new
> x.g #=> "A"
>
> def x.f; "B"; end
> x.g #=> "A"
>
> How do I get the last to return "B"? I know I could use
> '(class<<self;self;end)' instead of 'self.class', but that will create
> a singelton even if doesn't exist, which seems very wasteful. Yet I
> don't recall any (non-hack) way to detect if a singleton is defined. Is
> there?
>
> It would be nice if there was a reference with which we could call up
> through the class level like this.

Two ideas attached.

  robert

thanks robert. you helped clarify that unfortunately I've i mis-stated
the problem, there's a contradiction in my example, what I actually
meant was:

   class X
     def self.f ; "A" ; end
     def g ; self.class.f ; end
   end

   x = X.new
   x.g #=> "A"

   # this should be:
   class << x
     def self.f; "B"; end
   end

   x.g #=> "A" # want "B"

so #respond_to? won't help b/c I didn't intend #f to be instance level
method. sorry. what i'm asking for, should make a whole lot more sense
now (i hope)

thanks,
T.

···

On 18.11.2006 16:56, Trans wrote:

Just replace self.class with class<<self;self;end in my code.

  robert

···

On 18.11.2006 18:00, Trans wrote:

Robert Klemme wrote:

On 18.11.2006 16:56, Trans wrote:

I want to call a class level method from the the instance level, but I
need it to go through the singeton if it exists. Here is the most basic
example:

  class X
    def self.f ; "A" ; end
    def g ; self.class.f ; end
  end

  x = X.new
  x.g #=> "A"

  def x.f; "B"; end
  x.g #=> "A"

How do I get the last to return "B"? I know I could use
'(class<<self;self;end)' instead of 'self.class', but that will create
a singelton even if doesn't exist, which seems very wasteful. Yet I
don't recall any (non-hack) way to detect if a singleton is defined. Is
there?

It would be nice if there was a reference with which we could call up
through the class level like this.

Two ideas attached.

  robert

thanks robert. you helped clarify that unfortunately I've i mis-stated
the problem, there's a contradiction in my example, what I actually
meant was:

   class X
     def self.f ; "A" ; end
     def g ; self.class.f ; end
   end

   x = X.new
   x.g #=> "A"

   # this should be:
   class << x
     def self.f; "B"; end
   end

   x.g #=> "A" # want "B"

so #respond_to? won't help b/c I didn't intend #f to be instance level
method. sorry. what i'm asking for, should make a whole lot more sense
now (i hope)

thanks,
T.

How about this?

  robert

dispatch3.rb (711 Bytes)

···

On 18.11.2006 18:16, Robert Klemme wrote:

thanks robert. you helped clarify that unfortunately I've i mis-stated
the problem, there's a contradiction in my example, what I actually
meant was:

   class X
     def self.f ; "A" ; end
     def g ; self.class.f ; end
   end

   x = X.new
   x.g #=> "A"

   # this should be:
   class << x
     def self.f; "B"; end
   end

   x.g #=> "A" # want "B"

so #respond_to? won't help b/c I didn't intend #f to be instance level
method. sorry. what i'm asking for, should make a whole lot more sense
now (i hope)

thanks,
T.

Just replace self.class with class<<self;self;end in my code.

    robert

Robert Klemme wrote:

class Object
  # option 1
  def dispatch(m,*a,&b)
    [class <<self; self; end, self.class].find {|x| x.respond_to? m}.
      send(m,*a,&b)
  end

Nice. Looks like that'll work!

Thanks!

T.