[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

strange order of execution

Dirk Traulsen

3/29/2006 4:54:00 AM

Hi list!

I had a strange effect, when I combined print with several strings
and a method.
Please look at this example:

##############
def method1
print "string_2_method", " - "
return "return_string_method - "
end

print "\n"
print "string_1", " - ", method1, "string_3\n"
##############

Surprisingly it results in:
string_2_method - string_1 - return_string_method - string_3

But I expected it to result in:
string_1 - string_2_method - return_string_method - string_3

Even if any method would be executed first, independant of the
position in the line, then shouldn't it be the following:
string_2_method - return_string_method - string_1 - string_3

Can somebody please explain this strange order of execution to me?

Thanks
Dirk



15 Answers

Hal E. Fulton

3/29/2006 5:19:00 AM

0

Dirk Traulsen wrote:
>
> Can somebody please explain this strange order of execution to me?
>

All the arguments to your print are evaluated, including the
method call. So the stuff inside that method is printed first.
Then the print occurs normally (with your return value in place
of the method call). Thus your result.

However: Why would you ever do this? ;)


Hal



Just Another Victim of the Ambient Morality

3/29/2006 5:39:00 AM

0


"Dirk Traulsen" <dirk.traulsen@lypso.de> wrote in message
news:442A2F49.10564.F61BC9B@dirk.traulsen.lypso.de...
> Hi list!
>
> I had a strange effect, when I combined print with several strings
> and a method.
> Please look at this example:
>
> ##############
> def method1
> print "string_2_method", " - "
> return "return_string_method - "
> end
>
> print "\n"
> print "string_1", " - ", method1, "string_3\n"
> ##############
>
> Surprisingly it results in:
> string_2_method - string_1 - return_string_method - string_3
>
> But I expected it to result in:
> string_1 - string_2_method - return_string_method - string_3
>
> Even if any method would be executed first, independant of the
> position in the line, then shouldn't it be the following:
> string_2_method - return_string_method - string_1 - string_3
>
> Can somebody please explain this strange order of execution to me?

Interestingly enough, this doesn't really have anything to do with Ruby,
in particular...

In your example, "method1" is a method call that executes and returns a
value. You are calling it as a parameter to another method call, the one to
"print." Just in case it makes it more clear to you, I will add the
optional brackets like how you would have to in some other languages...

print("\n")
print( "string_1", "-", method1(), "string3\n");

So, you're calling "print" and passing it four parameters. But, with
the third parameter, you're passing in the return value of "method1."
Therefore, you need to call it and, as such, you will be calling it before
you call "print." But "method1" has a side effect. It calls:

print( "string_2_method", "-") # brackets added for possible clarity...

So, because "method1" is called first, the string printed from within
that method gets printed first, as its side effect. Then the return value
of that method gets returned to the caller, as a parameter to the method
call "print." So then "print" gets called with its four parameters and they
are printed, in that order.
Hopefully, the order of your printed strings is a mystery no more...

Again, this has nothing to do with Ruby. This will happen in any
procedural programming language that I can think of...


Dirk Traulsen

3/29/2006 5:53:00 AM

0

Am 29 Mar 2006 um 14:18 hat Hal Fulton geschrieben:

> Dirk Traulsen wrote:
> >
> > Can somebody please explain this strange order of execution to me?
> >
>
> All the arguments to your print are evaluated, including the
> method call. So the stuff inside that method is printed first.

Alright, so the method calls are executed first already during evaluation. I thought

print "string", method1

would be identical to

print "string"
print method1

> Then the print occurs normally (with your return value in place
> of the method call). Thus your result.

Ah, got it.

> However: Why would you ever do this? ;)

To improve my still humble Ruby knowledge I was analyzing scripts I
find on the net to see whether I understand them. I found this case
and couldn't understand the output.

Thanks for your help!
Dirk


Dirk Traulsen

3/29/2006 6:14:00 AM

0

Am 29 Mar 2006 um 14:43 hat Just Another Victim of the Am geschrieben:

>
> "Dirk Traulsen" <dirk.traulsen@lypso.de> wrote in message
(..)
> > Can somebody please explain this strange order of execution to > > > me?
(..)
> So, you're calling "print" and passing it four parameters. But, with
> the third parameter, you're passing in the return value of "method1."
> Therefore, you need to call it and, as such, you will be calling it before
> you call "print."

That was my misunderstanding. I thought

print "string", method1

would be identical to

print "string"
print method1

> So, because "method1" is called first, the string printed from
> within that method gets printed first, as its side effect.
> Then the return value
> of that method gets returned to the caller, as a parameter to the method
> call "print." So then "print" gets called with its four parameters and they
> are printed, in that order.
> Hopefully, the order of your printed strings is a mystery no more...

That is very clear now. Thanks a lot for the really good explanation.

I must say that I'm impressed by the fast and friendly help of this
list even in case of this clear beginner question.

Dirk



Robert Klemme

3/29/2006 6:57:00 AM

0

Dirk Traulsen wrote:
> Am 29 Mar 2006 um 14:18 hat Hal Fulton geschrieben:
>
>> Dirk Traulsen wrote:
>>> Can somebody please explain this strange order of execution to me?
>>>
>> All the arguments to your print are evaluated, including the
>> method call. So the stuff inside that method is printed first.
>
> Alright, so the method calls are executed first already during evaluation. I thought

The method invocation *is* the evaluation.

> print "string", method1
>
> would be identical to
>
> print "string"
> print method1

No, not at all. Btw, if you want to watch what's going on, you can
insert this at the top of your script and follow the execution as it's
printed

set_trace_func lambda {|*a| p a}

Kind regards

robert

Sergey Volkov

3/29/2006 7:38:00 AM

0

in lisp we have macro which does not evaluate arguments,
is it possible in Ruby?
Sergey

Robert Klemme

3/29/2006 8:25:00 AM

0

vsv wrote:
> in lisp we have macro which does not evaluate arguments,
> is it possible in Ruby?

No, unless you resort to putting your code into strings and evaluating
it later. IMHO this looks ugly most of the time - not to mention
efficiency. Is there something you cannot do without?

Kind regards

robert

Sergey Volkov

3/29/2006 8:50:00 AM

0

> Is there something you cannot do without?
can't name it now, but I don't have enough practical experience with
Ruby :(
btw: macros in lisp are expanded in compile time, so there is no any
efficiency lost.
I belive Ruby will get implemented in bytecode eventually, at that time
'compile' time evaluation feature will be required; and then, I hope,
we'll get 'read' time evaluation too (just dreaming :)

regars
Sergey

James Gray

3/29/2006 1:58:00 PM

0

On Mar 29, 2006, at 2:53 AM, vsv wrote:

> I belive Ruby will get implemented in bytecode eventually, at that
> time
> 'compile' time evaluation feature will be required; and then, I hope,
> we'll get 'read' time evaluation too (just dreaming :)

We have it today:

>> ruby_code = "2 + 2"
=> "2 + 2"
>> "2 + 2 = #{eval(ruby_code)}"
=> "2 + 2 = 4"

James Edward Gray II


Sergey Volkov

3/29/2006 2:40:00 PM

0

|> we'll get 'read' time evaluation too (just dreaming :)
|
|We have it today:
James, you are dreaming too :)

| >> ruby_code = "2 + 2"
|=> "2 + 2"
| >> "2 + 2 = #{eval(ruby_code)}"
|=> "2 + 2 = 4"
it's not reader, but run-time string expantion,
reader it would be, when you can get result after _read_;
now in Ruby:
>> gets
"#{2+2}"
=> "\"\#{2+2}\"\n"
string was read and returned unmodified;

btw: why eval in your sample? "#{ruby_code}" is good enough for
evaluation sample in string;

Sergey