Weird thing about hashes and keys?

Status
Not open for further replies.

Milena

The woman of many questions
Veteran
Joined
Jan 26, 2014
Messages
1,281
Reaction score
106
First Language
Irish
Primarily Uses
N/A
I came across a weird thing about hashes.

here's my code:

module RPGMakerWeb Message_If_Actor = { 1 => "Attack", 128 => "Attack 128!" }endclass Window_BattleLog < Window_Selectable #-------------------------------------------------------------------------- # * Display Skill/Item Use #-------------------------------------------------------------------------- def display_use_item(subject, item) if item.is_a?(RPG::Skill) add_text(subject.name + RPGMakerWeb.values[item.id]) unless item.message2.empty? wait add_text(item.message2) end else add_text(sprintf(Vocab::UseItem, subject.name, item.name)) end endendso apparently, I want the subject to say for example: "Eric: Attack 128"! if I use skill 128. As you can see on my hash I have 128 key. But whenever I execute the script, somehow the hash doesn't recognize 128 as a key and so it won't display the value of key 128. It says can't convert String to nil.

Also, if possible, is there a way to make the subject talk different words depending on if they're actors or not?
 

Shaz

Veteran
Veteran
Joined
Mar 2, 2012
Messages
40,098
Reaction score
13,704
First Language
English
Primarily Uses
RMMV
There's no such thing as RPGMakerWeb.values - you created RPGMakerWeb.message_if_actor which HAS a property called values.

Code:
add_text(subject.name + RPGMakerWeb::message_if_actor[item.id])
 
Last edited by a moderator:

Milena

The woman of many questions
Veteran
Joined
Jan 26, 2014
Messages
1,281
Reaction score
106
First Language
Irish
Primarily Uses
N/A
There's no such thing as RPGMakerWeb.values - you created RPGMakerWeb.message_if_actor which HAS a property called values.

add_text(subject.name + RPGMakerWeb.message_if_actor[item.id])or it might be RPGMakerWeb::message_if_actor[item.id]
Oh wait, I see. Let me check this out. 

Edit: This doesn't work. Still getting the nil error.

If I put in 2 as thet values it works, but when I use skill 128 which is the key I wanted, well it doesn't.
 
Last edited by a moderator:

Zalerinian

Jack of all Errors
Veteran
Joined
Dec 17, 2012
Messages
4,696
Reaction score
935
First Language
English
Primarily Uses
N/A
Please show a screenshot of the error. According to your first post, there is no value for 2.
 

nio kasgami

VampCat
Veteran
Joined
May 21, 2013
Messages
8,949
Reaction score
3,042
First Language
French
Primarily Uses
RMMV
simply you also need to input the to_s because this need to be convert into string 

but I think you have two proble ...but not sure but you have to do this 

def display_use_item(subject, item) @value = RPGMakerWeb::Message_If_Actor[item_id] if item.is_a?(RPG::Skill) add_text(subject.name + @value.to_s) unless item.message2.empty? wait add_text(item.message2) end else add_text(sprintf(Vocab::UseItem, subject.name, item.name)) end endendthe to_s allow to value to be  convert into string and don't call module instance directly in the method like that put it into a Global like ( @value ) it is better for comprension and advoid ridiculous bugs
 
Last edited by a moderator:

BoluBolu

Veteran
Veteran
Joined
Apr 24, 2014
Messages
452
Reaction score
117
Primarily Uses
@nio_kasgami
 

simply you also need to input the to_s because this need to be convert into string
This is not nedeed.
RPGMakerWeb::Message_If_Actor[128] should give the value of this : "Attack 128!"  <= which is already a string.
I mean the values inside the has is already string.
I believe the problem might be this RPGMakerWeb::message_if_actor[item.id] the message_if_actor is all in lowercase?  it should be Message_If_Actor
You need to give more info :)
 
 

FenixFyreX

Fire Deity
Veteran
Joined
Mar 1, 2012
Messages
434
Reaction score
310
First Language
English
Primarily Uses
@Shaz - Woah, not sure if you were confused as to whether the OP was using a method or not...your message_if_actor is lowercase, not a constant like the OP has in their code, so your explanation is error-prone and as the OP suggested, didn't work.

@OP - When we look at a hash, it is technically made up of two arrays: keys, and values. Each object in keys refers to the same-indexed value in the values array.

Now, in Ruby 1.9 and up, hashes are ordered; that is, when you create a key/value pair and add it to a hash, then it is the nth pair in the hash. Let's look at this hash:

module RPGMakerWeb  Message_If_Actor = {    1 => "Attack",    128 => "Atack 128!"  }end How do we access this hash? Well, it's a constant in the module RPGMakerWeb, so to access it, would look something like:

RPGMakerWeb::Message_If_Actor Now. When we use the #keys and #values methods of Hash, it returns separate arrays. We have added 1 => "Attack", then 128 => "Attack 128!", so the key and value arrays would look something like:

RPGMakerWeb::Message_If_Actor.keys   #=>   [1, 128]RPGMakerWeb::Message_If_Actor.values   #=> ["Attack", "Attack 128!"] So, we see that "Attack 128!" is index 1 of the values array. You have tried to do this:

RPGMakerWeb.values[128] There are two things wrong with this code; first of all, RPGMakerWeb is not the hash; it's the container module in which the hash is stored, so we change that to

RPGMakerWeb::Message_If_Actor.values[128] ..But it still errors! Ah, the reason for that is simple. When you call #values on the hash, it returns an array, not the hash itself! Therefore, the index you need to use is 1. This is why you need to leave out '.values', and do this instead:

RPGMakerWeb::Message_If_Actor[128] That is the correct code; see, when you access a hash, the value inbetween the []s is the 'key', and what is returned is the 'value'.

Hope this explanation helped :p
 
Last edited by a moderator:

Shaz

Veteran
Veteran
Joined
Mar 2, 2012
Messages
40,098
Reaction score
13,704
First Language
English
Primarily Uses
RMMV
which is pretty much what I had, without the lower case typo (sorry about that - I am way more familiar with calling methods than constants) ... and a much more interesting and helpful explanation :)


However, what happens if the hash doesn't contain the key? It's honestly too early in the morning for me to work through it, but does there need to be a .has_key? test in there somewhere, or a default value stored with the hash to return in case of no key?
 
Last edited by a moderator:

Another Fen

Veteran
Veteran
Joined
Jan 23, 2013
Messages
564
Reaction score
275
First Language
German
Primarily Uses
Did you get that error message when using
RPGMakerWeb.values

or

RPGMakerWeb::message_if_actor

?

As it was already stated above, none of these calls should work because the respective methods should not exist for a Module object, so I would have expected a corresponding error message (however, I don't know your entire scriptset of course and I might overlook something). Are you sure this line caused the error?

When you are sure you used the right call but are still getting funny results, consider to do a console output of all elements involved to check if they have correct values, for example

p RPGMakerWeb::Message_If_Actor, item.id
 

When you test a script using the Battle-Test-Mode from the database, be sure to save your project before you do. Otherwise the game won't use the latest scripts (you won't have to save when you just edited items in the database).

You can test if a battler is an actor by using either its actor? or enemy? method.
 
Last edited by a moderator:

FenixFyreX

Fire Deity
Veteran
Joined
Mar 1, 2012
Messages
434
Reaction score
310
First Language
English
Primarily Uses
@Shaz, that's where even the final code I posted would fall through; there should be a conditional if statement that checks whether the key is there or not, and only if there is, add the text. So,

Code:
my_value = RPGMakerWeb::Message_If_Actor[item.id]add_text("#{subject.name}#{my_value}" if my_value#...rest of the method
If we were to get down into details, the OP should alias the method, not overwrite it, and a few other things need to happen before the code is completely clean; however, they are learning! So these such things aren't expected to come instantly. :)
 

Shaz

Veteran
Veteran
Joined
Mar 2, 2012
Messages
40,098
Reaction score
13,704
First Language
English
Primarily Uses
RMMV
I was just thinking it might throw an error or give unwanted results if the key wasn't there, which would prompt another request for help :)
 

Milena

The woman of many questions
Veteran
Joined
Jan 26, 2014
Messages
1,281
Reaction score
106
First Language
Irish
Primarily Uses
N/A
Thanks for replying and for all the solutions. Normally, I wanted the item.id (which would be the id of the skill I just used) to be the ones given or thrown out as the value inside the hash. Here's my full code I tried:

module Heartfire module Message Actor_Quotes = { 128 => "Attack #128!" } endendclass Window_BattleLog < Window_Selectable #-------------------------------------------------------------------------- # * Display Skill/Item Use #-------------------------------------------------------------------------- def display_use_item(subject, item) if item.is_a?(RPG::Skill) if subject.is_a?(Game_Enemy) add_text(subject.name + Heartfire::Message::Actor_Quotes[item.id]) add_text(subject.name + item.message1) end unless item.message2.empty? wait add_text(item.message2) end else add_text(sprintf(Vocab::UseItem, subject.name, item.name)) end endendThe scenario is like this. I made a skill called Forbidden Attack, which is under 128th skill of the Skills Database. Now, whenever I use that skill, I wanted it to throw another line of quote when the actor uses it. I tried doing it without the .values and here's what happens:



So I was thinking what could have been wrong with it. 

If I used Skill #128, shouldn't this code:

add_text(subject.name + Heartfire::Message::Actor_Quotes[item.id])throw out the 128th key or numbered key's value on the Hash?
 
Last edited by a moderator:

Milena

The woman of many questions
Veteran
Joined
Jan 26, 2014
Messages
1,281
Reaction score
106
First Language
Irish
Primarily Uses
N/A
Thanks, now solved! Requesting the thread to be closed.
 

Shaz

Veteran
Veteran
Joined
Mar 2, 2012
Messages
40,098
Reaction score
13,704
First Language
English
Primarily Uses
RMMV
This thread is being closed, due to being solved. If for some reason you would like this thread re-opened, please report this post and leave a message why. Thank you.
 
Status
Not open for further replies.

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

Latest Threads

Latest Posts

Latest Profile Posts

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.
Do you Find Tilesetting or Looking for Tilesets/Plugins more fun? Personally I like making my tileset for my Game (Cretaceous Park TM) xD
How many parameters is 'too many'??

Forum statistics

Threads
105,867
Messages
1,017,061
Members
137,575
Latest member
akekaphol101
Top