def if ; end - basically impossible?

G

Giles Bowkett

I'm writing some code which needs to do something unusual when it
encounters an if, an else, or an end.
=> nil

The ?> line comes up because if appears to not be a method but an
operator or something similar, so my override does nada.

Is there any way to do this? It looks as if I have to either rethink
my strategy or write some kind of parser.

--
Giles Bowkett

Podcast: http://hollywoodgrit.blogspot.com
Blog: http://gilesbowkett.blogspot.com
Portfolio: http://www.gilesgoatboy.org
Tumblelog: http://giles.tumblr.com
 
R

Rick DeNatale

I'm writing some code which needs to do something unusual when it
encounters an if, an else, or an end.

=> nil

The ?> line comes up because if appears to not be a method but an
operator or something similar, so my override does nada.

Is there any way to do this? It looks as if I have to either rethink
my strategy or write some kind of parser.

If is not a method, it's a reserved word.

Ruby doesn't have many reserved words, but it has a few: __FILE__ ,
__LINE__, alias. and ,begin, BEGIN, break, case, class, def
,defined?, do, else, elsif, end, END, ensure, false. for, if, in, or,
module, next, nil, not, redo, rescue, retry, return, self, super,
then, true, undef, unless, until, when, while, and yield
 
J

Johan Veenstra

[Note: parts of this message were removed to make it a legal post.]

2007/12/28 said:
I'm writing some code which needs to do something unusual when it
encounters an if, an else, or an end.

=> nil

The ?> line comes up because if appears to not be a method but an
operator or something similar, so my override does nada.

Is there any way to do this? It looks as if I have to either rethink
my strategy or write some kind of parser.
You have defined a function namen "if", and you can call this function with
send:)if),
but this doesn't override the if-else/elsif-end construct.
 
P

Paul Brannan

I'm writing some code which needs to do something unusual when it
encounters an if, an else, or an end.

=> nil

The ?> line comes up because if appears to not be a method but an
operator or something similar, so my override does nada.

Is there any way to do this? It looks as if I have to either rethink
my strategy or write some kind of parser.

It works if you call #if on an object. I do something like this in
ruby-libjit:

class Function
def if(condition, &block)
# append code to:
# - if the condition is true, execute the code appended by the
# block
# - if the condition is false, branch to the end label
block.call
return If.new(self)
end

class If
def initialize(function)
@function = function
end

def end
# append the end label here
end
end
end

so I can write something like:

Function.compile do |f|
f.if(<condition>) {
# true case
} .else {
# false case
} .end

end

(I've omitted the code for #else for simplicity, because it really makes
the code complicated)

Paul
 
G

Giles Bowkett

(I've omitted the code for #else for simplicity, because it really makes
the code complicated)

Could I see it? It looks as if ruby-libjit has no releases (according
to RubyForge) and I think I'll probably use your technique to make
this happen. Right now I'm passing blocks to a code generator, like
this:

Generator.module_eval(&block)

I could probably do something which treats the code as strings, and
either passes them off to module_eval(&block) like this, *or* passes
them to send:)if) instead. Even a simple case statement might work.

--
Giles Bowkett

Podcast: http://hollywoodgrit.blogspot.com
Blog: http://gilesbowkett.blogspot.com
Portfolio: http://www.gilesgoatboy.org
Tumblelog: http://giles.tumblr.com
 
S

Sam Smoot

Generator.module_eval(&block)

If you're passing the code as a block, the easiest solution may be
ParseTree? I haven't toyed with it, but Ryan Davis also just released
ruby_parser apparently, which seems to be a pure-ruby version of
ParseTree.
 
G

Giles Bowkett

Generator.module_eval(&block)
If you're passing the code as a block, the easiest solution may be
ParseTree? I haven't toyed with it, but Ryan Davis also just released
ruby_parser apparently, which seems to be a pure-ruby version of
ParseTree.

I think that's correct; it's either a Ruby port or a Ruby equivalent.
But it returns s-exps; what I really need is to catch ifs and send
them to an if method.

--
Giles Bowkett

Podcast: http://hollywoodgrit.blogspot.com
Blog: http://gilesbowkett.blogspot.com
Portfolio: http://www.gilesgoatboy.org
Tumblelog: http://giles.tumblr.com
 
S

Sam Smoot

I think that's correct; it's either a Ruby port or a Ruby equivalent.
But it returns s-exps; what I really need is to catch ifs and send
them to an if method.


Right. I guess I meant it would seem like you could use ParseTree (or
something similar) to detect if/elsif/else/end constructs, and then re-
evaluate their interiors as a new proc (I *think* ParseTree can
compile a S-Exp to Ruby, but I haven't tried that side personally).
That way, you could evaluate the condition, and then send the correct
branch along.

I guess my assumption is that you don't necessarily *need* to have a
method called :if if you can properly detect/handle `if` keywords in
the blocks. But that assumption could be off base. Maybe your whole
point is building a DSL with :if methods to use. I dunno. Best of
luck. :)
 
P

Paul Brannan

Giles said:
Could I see it? It looks as if ruby-libjit has no releases (according
to RubyForge) and I think I'll probably use your technique to make
this happen.

You should be able to check the code out of svn.
Right now I'm passing blocks to a code generator, like this:

Generator.module_eval(&block)

I could probably do something which treats the code as strings, and
either passes them off to module_eval(&block) like this, *or* passes
them to send:)if) instead. Even a simple case statement might work.

I'm having a hard time imaging what you are describing.

You should be able to use self.if instead of send:)if).

Paul
 
G

Giles Bowkett

You should be able to check the code out of svn.

Whoops! Duh. Will do.
I'm having a hard time imaging what you are describing.

You should be able to use self.if instead of send:)if).

The thing is, I want to be able to do this:

generating_code(ForSomething) do
if variable != some_condition
do :stuff
else
do:)other => stuff)
end
end

And basically *not* use the if or else built into Ruby. I can do it
very easily if I do this:

gen_code(Etc) do
"if asdf == qwerty" # etc
end

but that's cheating because it's using strings and I want to use actual code.

The solution I came up with is kinda booty. Basically it goes like this:

generating(Code) do |variable|
variable.> value do
stuff
end
variable.<= value do
other :stuff
end
end

it seems to be the best solution available to me at the moment but a
better solution would be better. obviously.

--
Giles Bowkett

Podcast: http://hollywoodgrit.blogspot.com
Blog: http://gilesbowkett.blogspot.com
Portfolio: http://www.gilesgoatboy.org
Tumblelog: http://giles.tumblr.com
 
P

Paul Brannan

Giles said:
generating_code(ForSomething) do
if variable != some_condition
do :stuff
else
do:)other => stuff)
end
end

The only way I know to make this work is to use parsetree or nodewrap to
build a custom parser for the block. I've tinkered with doing this, but
it always turns out too hard for the user (actually, everything's easy
except for how Ruby handles local variables -- I think need to build an
intermediate representation for the Ruby code that can be easily
transformed).

The solution you came up with is probably cleaner, at least for the time
being.

Paul
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top