Finding methods inside a scope

Suppose I have a scope

plate do
serve do |d|
d.pizza 2
d.momo 5
end

eat do |d|
  d.pizza 1
  d.momo 2
end

end

Is there a way to find that exactly two methods, namely serve and eat
have been defined under plate’s scope.

Hi,

Those are method calls, not method definitions.

I’m pretty sure listing method calls is complicated and requires a deep
analysis of Ruby internals. What do you need that for?

I’m instance_eval-ing the plate block and then trying to hook up method
missing to call serve and eat methods. The problem is that this is on a
class level scope so every-undefined-method passes on to method missing.
I could get away with defining a pattern and then using a regex but
since it is enclosed in the plate block, I was wondering if there was a
more natural way available to infer methods/method calls that happen
inside the block scope. Does this make sense?

On Wed, Aug 22, 2012 at 6:04 PM, Dipesh G. [email protected]
wrote:

I’m instance_eval-ing the plate block and then trying to hook up method
missing to call serve and eat methods. The problem is that this is on a
class level scope so every-undefined-method passes on to method missing.

Yes, that’s regular behavior for every object.

I could get away with defining a pattern and then using a regex but
since it is enclosed in the plate block, I was wondering if there was a
more natural way available to infer methods/method calls that happen
inside the block scope. Does this make sense?

I still do not understand what your issue is: if you know where you
want to invoke those methods then method_missing can simply delegate
to the instance. Other than that, what else do you want to do with
methods which are not defined and of which you do not know where they
are?

Can you show more code, namely the code which invokes instance_eval
and demonstrate what it is supposed to do?

Cheers

robert

On Wed, Aug 22, 2012 at 1:45 PM, Jan E. [email protected] wrote:

Those are method calls, not method definitions.

Also the call to #plate does not introduce a scope. If at all the
scope is opened by the block passed to #plate.

I’m pretty sure listing method calls is complicated and requires a deep
analysis of Ruby internals.

For a first start one can do

plate do
p method(:serve), method(:eat)

serve do |d|
  d.pizza 2
  d.momo 5
end

eat do |d|
  d.pizza 1
  d.momo 2
end

end

The output will tell you something about the class in which the method
is defined.

What do you need that for?

I second that question.

Kind regards

robert

On Mon, Aug 27, 2012 at 4:12 PM, Dipesh G. [email protected]
wrote:

Sorry, I should have posted more code. The code below does not work but
I
think you will get the idea.

class Food
def plate(&block)
extend Operators
include Operations

That line above does not make sense since you can only include a
module in a class or module. Also, it’s a questionable habit to
extend multiple times with the same module. That is inefficient.

instance_eval(&block)
end

plate do
eat do |d|
d.pepsi, 20
d.coke, 10
end
end

Method plate is not defined for the class. Also it’s a bad idea to
have similarly named methods for class and instance.

end
I wanted it to trigger the pepsi and coke methods on instance level with
corresponding
arguments. I have not included those methods here though.

Why? How are we supposed to understand your use case?

I wanted to define my methods inside the Operations module via method
missing. But since it was extended, I was looking for a scope to tie up
to.

Hope that made sense.

Frankly, no - at least not to me.

And Thanks. If you guys say there’s a better way
available, I would be happy to post the working code.

I would need to understand what your goal is. It’s not clear to me
yet. Can you describe your use case more abstractly than with a
solution in mind? What are your requirements and goals?

Cheers

robert

Sorry, I should have posted more code. The code below does not work but
I
think you will get the idea.

class Food
def plate(&block)
extend Operators
include Operations
instance_eval(&block)
end

plate do
eat do |d|
d.pepsi, 20
d.coke, 10
end
end

end

module Operations
attr_accessor :bloc
def serve(&block)
@bloc[:serve] = block
end
def eat(&block)
@bloc[:eat] = block
end
end

module Operators
def serve!
@bloc[:serve].call(self)
end
end

Then, when I do
Food.new.serve!

I wanted it to trigger the pepsi and coke methods on instance level with
corresponding
arguments. I have not included those methods here though.

I wanted to define my methods inside the Operations module via method
missing. But since it was extended, I was looking for a scope to tie up
to.

But, I got it wrong there. Later, I got around it by doing something
like:

class Food

def plate(&block)
@current_scope = method
instance_eval(&block)
@current_scope = nil
end

end

module Operations
def method_missing(m,*a,&b)
if @current_scope == :plate
@bloc[:m] = b
else
super
end
end
end

Hope that made sense. And Thanks. If you guys say there’s a better way
available, I would be happy to post the working code.

Hi,

To put it bluntly: I think you’ve kind of got lost in all that
metaprogramming magic and forgot what you actually want to do. We’ve
asked you again and again about your goal, and you could never give a
concrete answer (and your code doesn’t tell either).

Your code is so packed with obscure techniques (like all that module
extending) and strange dependencies
that I find it almost impossible to read. When I see something like
this, I immediately think: This guy (or gal) doesn’t think clearly.

Even complex algorithms usually don’t use metaprogramming that heavily.
So I think there’s something wrong with how you program. You’ve almost
developed your own “pseudo-OOP” where you use modules and extending
instead of classes and inheritance.

I know this doesn’t sound nice, but what I would do is completely dump
the code and start from scratch. First you should ask yourself: What do
I want to achieve? Why do I even need the code? Then you should create
an appropriate and simple object model. Use metaprogramming only when
it’s actually necessary. The normal way of doing things is using classes
and fixed methods.

Of course we can also help you with the concept. But then we’ll need a
concrete goal. Something like “I want to write a database wrapper” or “I
want to write a text-based adventure game”.

What I was trying to do was to define methods inside Events via
method_missing.

Hmm…
At certain events of my program, I send an email(whose template differs
on what event just happened), update some redis statistics, create and
update some database entries and do some other calculations. I do this
set of actions repetitively for 12-15 events, for some events, I might
not need to send an email or create a db entry and such. I wanted to
create a nice
DSL and then keep the actual methods separate from the class which was
turning into a hell of method calls. I was thinking the DSL would serve
as a easy place to change things on a higher level, that was what I had
in mind.

And no, it actually sounds nice to dump the code but I fear I will
somehow be going along the same path again.

On Mon, Aug 27, 2012 at 7:37 PM, Dipesh G. [email protected]
wrote:

Hmm…
At certain events of my program, I send an email(whose template differs
on what event just happened), update some redis statistics, create and
update some database entries and do some other calculations. I do this
set of actions repetitively for 12-15 events.

Do you mean 12-15 different types of events?

I wanted to create a nice
DSL and then keep the actual methods separate from the class which was
turning into a hell of method calls. I was thinking the DSL would serve
as a point of contact, that was what I had in mind.

Are users supposed to change the handling of events?

And no, it actually sounds nice to dump the code but I fear I will
somehow be going along the same path again.

:slight_smile: Maybe we can counsel you to some clarifications of what you are
trying to do. I found that lacking clarity is one source for badly
structured code. And talking to others - especially from the same
field - helps in finding clarity in one’s own mind. I can only speak
for me of course but I have observed the phenomenon with a few
colleagues as well so I reckon it must be generally helpful to
communicate about ideas and code.

Kind regards

robert