How to save (marshal_dump) with class Proc?

Cinnamon

Veteran
Veteran
Joined
Jun 20, 2014
Messages
605
Reaction score
209
First Language
English
Primarily Uses
RPG Maker XP:

I'm using a Pathfinding script (A_Star_Pathfinder) that apparently creates a Proc when defining a part of the pathfinding (reach_method or fail_method).

Problem is that when the player tries to save while a path such as that exists, I get this error:

Script 'Window Save' line 375: TypeError occurred.

 

that line is: Marshal.dump($game_map, file)

 

no marshal_dump is defined for class Proc

 

Any idea how to work around this? Create a rescue function that stops the game from saving if it runs into a problem? Get the "Proc" to save? I don't know what a Proc is or how it works so I'm really lost here.
 
Last edited by a moderator:

TheoAllen

Self-proclaimed jack of all trades
Veteran
Joined
Mar 16, 2012
Messages
5,592
Reaction score
6,522
First Language
Indonesian
Primarily Uses
RMVXA
Link to the script please?
 

Cinnamon

Veteran
Veteran
Joined
Jun 20, 2014
Messages
605
Reaction score
209
First Language
English
Primarily Uses
It's a custom script to Unraveled, but it functions the same as this:

http://www.hbgames.org/forums/viewtopic.php?p=531338

But I literally have no idea what a Proc is or how it works, otherwise I can usually figure these things out myself. I don't understand why a "Proc" can't be saved using marshal_dump.

Here's a code calling the pathfinding:

path = A_Star_Pathfinder.new

n = Node.new(47, 11)

id = 119

reach = lambda { turn_right(119) }

path.setup(n,id,0,false,reach)

path.calculate_path

path.generate_path

 

Basically upon reach it turns event 119 to the right. If I save before the path is reached, I get the save error.

@

Dreadshadow: Thank you. :p
 
Last edited by a moderator:

TheoAllen

Self-proclaimed jack of all trades
Veteran
Joined
Mar 16, 2012
Messages
5,592
Reaction score
6,522
First Language
Indonesian
Primarily Uses
RMVXA
You could easily move Proc to temporary object like $game_temp to be used as public variable.

Do not put Proc into any saved content objects like $game_system, $game_player, or $game_actors

EDIT:

Oh, it was RMXP lol

Well since it also a custom script, I can't help so much.
 
Last edited by a moderator:

Cinnamon

Veteran
Veteran
Joined
Jun 20, 2014
Messages
605
Reaction score
209
First Language
English
Primarily Uses
The weird thing is, I can't find a "Proc.new" anywhere in the pathfinding script. Is this:

reach = lambda { turn_right(119) }

Creating a Proc? Lambda is the same as Proc? 
 

TheoAllen

Self-proclaimed jack of all trades
Veteran
Joined
Mar 16, 2012
Messages
5,592
Reaction score
6,522
First Language
Indonesian
Primarily Uses
RMVXA
AFAIK, they're same
 

Cinnamon

Veteran
Veteran
Joined
Jun 20, 2014
Messages
605
Reaction score
209
First Language
English
Primarily Uses
It's basically the same as the script I posted, there are no technical differences.

Trying to read the script...

I'm guessing that the lambda/Proc gets stored in the path, the path gets stored in the event and the event is stored in $game_map, thus creating the save error. So I don't see how I can easily move that to $game_temp...

Here in the script the "reach method" is called:

                if @a_star_paths[0].reach_method

                  @a_star_paths[0].reach_method.call

                end

 

And in Class Interpreter I added:

 

  def turn_right(id)

    return if id == nil

    $game_map.events[id].direction = 6

  end

  

etc.

 

to be able to turn characters using this method.

 

I'm thinking, is it possible to turn a Proc into something else that is saveable? Maybe convert the Proc into a string then back into a Proc when called? That way when saved it's a string, not a Proc, but it still functions.

 

I don't know if that's a possibility?

 

Otherwise I'll look into saving the reach_method in $game_temp somehow, but then when you save and load it kinda fricks up the game. And I seem to remember from my custom message system that it's possible to go from code to string to code.

 

Edit: It looks like I'm not the only one looking for a way to extract the code from a Proc:

 

http://stackoverflow.com/questions/4811501/how-to-extract-the-code-from-a-proc-object

 

Would you happen to know how to do it in RGSS?
 
Last edited by a moderator:

Evgenij

Veteran
Veteran
Joined
Aug 28, 2013
Messages
349
Reaction score
100
First Language
German
Primarily Uses
N/A
<p>You could for example make this like this:</p>

<pre class="_prettyXprint _lang-">

path = A_Star_Pathfinder.new

n = Node.new(47, 11)

id = 119

reach = "lambda { turn_right(119) }"

path.setup(n,id,0,false,reach)

path.calculate_path

path.generate_path

</pre>

<p>Make the lambda a string.</p>

<p>Then you need to change how the script handles the calls:</p>

<p>

</p><p>Line 388:</p>

<pre class="_prettyXprint _lang-">

@fail_method.call

</pre>

<p>to:</p>

<pre class="_prettyXprint _lang-">

eval(@fail_method).call

</pre>

<p> </p>

<p>Line 765:</p>

<pre class="_prettyXprint _lang-">

@a_star_paths[0].reach_method.call

</pre>

<p>to:</p>

<pre class="_prettyXprint _lang-">

eval(@a_star_paths[0].reach_method).call

</pre>

<p> </p>

<p>Line 844:</p>

<p> </p>

<pre class="_prettyXprint">

@a_star_paths[0].fail_method.call</pre>

<p>to:</p>

<pre class="_prettyXprint _lang-">

eval(@a_star_paths[0].fail_method).call

</pre>

<p>
</p><p> </p>

<p>I dont know if this will work but you can try it out. Keep in mind that evaluating the code is slower than just calling the proc, so if you see any performance loss you will need to think of another way.</p>
 

Cinnamon

Veteran
Veteran
Joined
Jun 20, 2014
Messages
605
Reaction score
209
First Language
English
Primarily Uses
^

Wow, what's going on with your post? o_O

Unfortunately lambda's are all over the game so a Proc > string command would be preferable to having to re-edit all the events. If one exists? If not I'll look into that option. :) Thanks.
 
Last edited by a moderator:

Evgenij

Veteran
Veteran
Joined
Aug 28, 2013
Messages
349
Reaction score
100
First Language
German
Primarily Uses
N/A
I dont know what happened to my post, looks like its in html format xD

There is no easy way to change all the events automatically. And cause I dont have rpg maker xp im limited in helping you.
 

Tsukihime

Veteran
Veteran
Joined
Jun 30, 2012
Messages
8,564
Reaction score
3,846
First Language
English
I would suggest replacing the whole lambda/proc thing and just building a move route object and then executing the move route.
 

Another Fen

Veteran
Veteran
Joined
Jan 23, 2013
Messages
564
Reaction score
275
First Language
German
Primarily Uses
Don't forget the proc does not only remember a code block but also the context the code is executed in, including local variables. So evaluating the code again won't guarantee the same behaviour when done for a different context.

One way could be to rewrite the script to accept symbols instead of procs, which are used to call an associated method.

Or - if you use the lambdas only for simple method calls - you could replace them by something else with a suitable call method, for example:

class Method_Sender   def initialize(target, method, *args)    @target = target    @args = [method] << args  end   def call    @target.send(*@args)  endendclass Interpreter   def sender(target, method, *args)    Method_Sender.new(target, method, *args)  endend
Here you could use sender(self, :turn_right, 117) instead of lambda { turn_right(117) } for a similar effect.

EDIT: Uhhh... at least that sounded to be a good idea when I came up with it...
 
Last edited by a moderator:

Cinnamon

Veteran
Veteran
Joined
Jun 20, 2014
Messages
605
Reaction score
209
First Language
English
Primarily Uses
Thanks for the comments, guys.

So I ended up basically calling the Proc right away, storing it as a manual number and based on that performing the action later... It's a bit clumsy and amateur but works. Kinda a custom move route object I guess, ha.

am curious now, though, is if it is possible to access the Proc's code block? I can't seem to find anything that allows you to access any information from the Proc. xD
 

Solistra

Veteran
Veteran
Joined
Aug 15, 2012
Messages
593
Reaction score
247
Primarily Uses
am curious now, though, is if it is possible to access the Proc's code block? I can't seem to find anything that allows you to access any information from the Proc. xD
This is possible in Rubinius, which is a separate implementation of the Ruby interpreter than the one used by RPG Maker (which would be MRI, the official interpreter for the language). Unfortunately, no, you cannot access the actual code stored by a Proc object in MRI.


TL;DR: No.
 

Cinnamon

Veteran
Veteran
Joined
Jun 20, 2014
Messages
605
Reaction score
209
First Language
English
Primarily Uses
This is possible in Rubinius, which is a separate implementation of the Ruby interpreter than the one used by RPG Maker (which would be MRI, the official interpreter for the language). Unfortunately, no, you cannot access the actual code stored by a Proc object in MRI.

TL;DR: No.
Thank you. :)
 

Users Who Are Viewing This Thread (Users: 0, Guests: 1)

Latest Threads

Latest Posts

Latest Profile Posts

People3_5 and People3_8 added!

so hopefully tomorrow i get to go home from the hospital i've been here for 5 days already and it's driving me mad. I miss my family like crazy but at least I get to use my own toiletries and my own clothes. My mom is coming to visit soon i can't wait to see her cause i miss her the most. :kaojoy:
Couple hours of work. Might use in my game as a secret find or something. Not sure. Fancy though no? :D
Holy stink, where have I been? Well, I started my temporary job this week. So less time to spend on game design... :(
Cartoonier cloud cover that better fits the art style, as well as (slightly) improved blending/fading... fading clouds when there are larger patterns is still somewhat abrupt for some reason.

Forum statistics

Threads
105,868
Messages
1,017,083
Members
137,583
Latest member
write2dgray
Top