How can I access the value returned by the previous expression? *(without getting it explicitly using an assignment) For example, executing the following file: ----------------------------------------- def my_method "a string" print_last_returned_object "another string" print_last_returned_object end def print_last_returned_object puts "#{ ??? }" end ^^^ What goes here? my_method() ----------------------------------------- Should result in: ----------------------------------------- > a string > another string ----------------------------------------- being printed to stdout. Any help on this is appreciated. Best, Erich
Um. "a string" never gets returned. Only the last statement in a function gets returned. (unless you use the return keyword). On Apr 8, 2005 5:01 PM, Erich Ocean <subscriber-npdh1YFn4ZDQT0dZR+AlfA@public.gmane.org> wrote:> How can I access the value returned by the previous expression? > *(without getting it explicitly using an assignment) > > For example, executing the following file: > > ----------------------------------------- > def my_method > "a string" > print_last_returned_object > > "another string" > print_last_returned_object > end > > def print_last_returned_object > puts "#{ ??? }" > end ^^^ What goes here? > > my_method() > ----------------------------------------- > > Should result in: > > ----------------------------------------- > > a string > > another string > ----------------------------------------- > > being printed to stdout. > > Any help on this is appreciated. > > Best, Erich > > _______________________________________________ > Rails mailing list > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails >
Well, isn''t "" the string constructor--just like calling String::New( "a string" )? I''m assuming it''s being returned from that function call. Every statement in Ruby, to my knowledge, has a return value. I didn''t think that "" was an exception. (Yes, I understand the ambiguity with the "" in the constructor call. The quotes are for the parser''s benefit; it shouldn''t result in the creation of an extra string object (only to be thrown away seconds later). Ruby may not be implemented that way, though, but the point still stands: "" should be shorthand for the string object constructor, which returns a string object.) Best, Erich On Apr 8, 2005, at 5:08 PM, Joe Van Dyk wrote:> Um. "a string" never gets returned. Only the last statement in a > function gets returned. (unless you use the return keyword). > > On Apr 8, 2005 5:01 PM, Erich Ocean <subscriber-npdh1YFn4ZDQT0dZR+AlfA@public.gmane.org> wrote: >> How can I access the value returned by the previous expression? >> *(without getting it explicitly using an assignment) >> >> For example, executing the following file: >> >> ----------------------------------------- >> def my_method >> "a string" >> print_last_returned_object >> >> "another string" >> print_last_returned_object >> end >> >> def print_last_returned_object >> puts "#{ ??? }" >> end ^^^ What goes here? >> >> my_method() >> ----------------------------------------- >> >> Should result in: >> >> ----------------------------------------- >>> a string >>> another string >> ----------------------------------------- >> >> being printed to stdout. >> >> Any help on this is appreciated. >> >> Best, Erich >> >> _______________________________________________ >> Rails mailing list >> Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org >> http://lists.rubyonrails.org/mailman/listinfo/rails >> > _______________________________________________ > Rails mailing list > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails >
Erich, On 09/04/2005, at 10:01 AM, Erich Ocean wrote:> How can I access the value returned by the previous expression? > *(without getting it explicitly using an assignment)I don''t have a deep understanding of Ruby so I could be wrong, but I''m pretty sure that you can''t do this. Even if there was some way of finding this out within the scope of my_method, I doubt you could do it in print_last_returned_object. The important question: Why on earth would you want to do this? What''s wrong with: x = "a string" print x or print "a string" Cheers, Pete Yandell
On Apr 8, 2005, at 6:23 PM, Pete Yandell wrote:> Erich, > > On 09/04/2005, at 10:01 AM, Erich Ocean wrote: > >> How can I access the value returned by the previous expression? >> *(without getting it explicitly using an assignment) > > I don''t have a deep understanding of Ruby so I could be wrong, but I''m > pretty sure that you can''t do this. Even if there was some way of > finding this out within the scope of my_method, I doubt you could do > it in print_last_returned_object.Well, if instead I was matching against a regex in the lines where I''m creating a string object, I could get the last match from the other method because it''s stored in a global variable. I was *hoping* that Ruby did the same thing for the return value of every expression: just store a reference to the last object returned from an expression in a global variable.> The important question: Why on earth would you want to do this?Take Rake, for example: ------------------------------ desc "my Rake task" task :some_task do |t| #something end ------------------------------ #desc simply stores the string passed to it in a variable, so that a subsequent call to `task` can retrieve that string. If the last returned value from an expression existed, you could eliminate the `desc` call and the variable. A Rakefile would be cleaner and look like this: ------------------------------ "my Rake task" task :some_task do |t| #something end ------------------------------ In this case, it''s a small improvement, but here''s the code that I''m working with (like Rake, I''m implementing a "language" with pure ruby): ------------------------------ fsm :cComment do fsm ''/*'' * fsm :extend { all :priority => 0 } fsm ''*/'' { accept :priority => 1 } end ------------------------------ If I had access to the last returned object, I could instead write: ------------------------------ fsm :cComment do ''/*'' * fsm :extend { all :priority => 0 } fsm ''*/'' { accept :priority => 1 } end ------------------------------ and retrieve the `''/*''` string during the #* method and call `fsm ''/*''` automatically. There are other uses. In Spirit (part of Boost) operators are overloaded to make it easy to build up a parser. If the first object is not a Spirit object, though, the operator applied is the built-in (C++) one, not the Spirit reimplimentation. That doen''t work. Subsequent objects can be the default objects if the first is a Spirit object--they''ll be transparently converted into Spirit objects. So you can''t do this in Spirit: ------------------------------ ''a'' << ''b'' // match an ''a'', followed by a ''b'' (doesn''t work) ------------------------------ because the first ''a'' is just a char -- it''s not a Spirit char parser. You have to use this instead: ------------------------------ char_p(''a'') << ''b'' // this works ------------------------------ I don''t have this particular problem (I override methods in String, which you can''t do in C++), but I would like to allow concatenation to proceed over multiple lines, like this: fsm :ab_parser do ''a'' ''b'' end This would match an ''a'', followed by a ''b''. Right now, I have to do: fsm :ab_parser do fsm ''a'' fsm ''b'' end I end up calling #fsm a lot. It''s not the end of the world, but I''d like it to be easier/cleaner if possible. Best, Erich
Erich, I understand what your trying to do and racked my brains to find some answer--but I don''t think this is possible. There are two ways to go, however, that might help (maybe). First, you can use quotes and just not close the quote until the next line: fsm :ab_parser do ''a b'' end This block will return "a\nb" which could (potentially) then be passed through "eval" to find out the values of a and b (either using @a and @b instead so that the values are still in scope outside of the block, or else by passing an additional reference to a Binding object). Second, irb. I actually don''t know how irb works, but it occurred to me that somehow irb is aware of the return value of every line of code it executes. I suspect that in order to implement this solution you would need to create a simple pre-parser that takes in an entire ruby text file and runs "eval" on each line. In this way, you could "catch" the return value and do what you want with it. What does this have to do with Rails anyway? :) Duane Johnson (canadaduane) On Apr 9, 2005 2:17 AM, Erich Ocean <subscriber-npdh1YFn4ZDQT0dZR+AlfA@public.gmane.org> wrote:> > On Apr 8, 2005, at 6:23 PM, Pete Yandell wrote: > > > Erich, > > > > On 09/04/2005, at 10:01 AM, Erich Ocean wrote: > > > >> How can I access the value returned by the previous expression? > >> *(without getting it explicitly using an assignment) > > > > I don''t have a deep understanding of Ruby so I could be wrong, but I''m > > pretty sure that you can''t do this. Even if there was some way of > > finding this out within the scope of my_method, I doubt you could do > > it in print_last_returned_object. > > Well, if instead I was matching against a regex in the lines where I''m > creating a string object, I could get the last match from the other > method because it''s stored in a global variable. I was *hoping* that > Ruby did the same thing for the return value of every expression: just > store a reference to the last object returned from an expression in a > global variable. > > > The important question: Why on earth would you want to do this? > > Take Rake, for example: > > ------------------------------ > desc "my Rake task" > task :some_task do |t| > #something > end > ------------------------------ > > #desc simply stores the string passed to it in a variable, so that a > subsequent call to `task` can retrieve that string. If the last > returned value from an expression existed, you could eliminate the > `desc` call and the variable. A Rakefile would be cleaner and look like > this: > > ------------------------------ > "my Rake task" > task :some_task do |t| > #something > end > ------------------------------ > > In this case, it''s a small improvement, but here''s the code that I''m > working with (like Rake, I''m implementing a "language" with pure ruby): > > ------------------------------ > fsm :cComment do > fsm ''/*'' > * fsm :extend { all :priority => 0 } > fsm ''*/'' { accept :priority => 1 } > end > ------------------------------ > > If I had access to the last returned object, I could instead write: > > ------------------------------ > fsm :cComment do > ''/*'' > * fsm :extend { all :priority => 0 } > fsm ''*/'' { accept :priority => 1 } > end > ------------------------------ > > and retrieve the `''/*''` string during the #* method and call `fsm ''/*''` > automatically. > > There are other uses. > > In Spirit (part of Boost) operators are overloaded to make it easy to > build up a parser. If the first object is not a Spirit object, though, > the operator applied is the built-in (C++) one, not the Spirit > reimplimentation. That doen''t work. Subsequent objects can be the > default objects if the first is a Spirit object--they''ll be > transparently converted into Spirit objects. > > So you can''t do this in Spirit: > > ------------------------------ > ''a'' << ''b'' // match an ''a'', followed by a ''b'' (doesn''t work) > ------------------------------ > > because the first ''a'' is just a char -- it''s not a Spirit char parser. > You have to use this instead: > > ------------------------------ > char_p(''a'') << ''b'' // this works > ------------------------------ > > I don''t have this particular problem (I override methods in String, > which you can''t do in C++), but I would like to allow concatenation to > proceed over multiple lines, like this: > > fsm :ab_parser do > ''a'' > ''b'' > end > > This would match an ''a'', followed by a ''b''. Right now, I have to do: > > fsm :ab_parser do > fsm ''a'' > fsm ''b'' > end > > I end up calling #fsm a lot. It''s not the end of the world, but I''d > like it to be easier/cleaner if possible. > > Best, Erich > > _______________________________________________ > Rails mailing list > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails >