Feature - Implemented Value of to_string() is prefixed with item number for ambiguously-named items

Code:
[COLOR="#DAA520"]> ash to_string($item[Spookyraven Library Key]);[/COLOR]

Multiple matches for "Spookyraven Library Key"; using "[7302]Spookyraven library key". () Clarify by using one of:
$item[[1764]Spookyraven library key]
$item[[7302]Spookyraven library key]
Returned: [7302]Spookyraven library key

[COLOR="#DAA520"]> ash to_string($item[[7302]Spookyraven Library Key]);[/COLOR]

Returned: [7302]Spookyraven library key

I recognize that maybe I shouldn't be using to_string($item[X]) to do this, since there's no to_string(item), so it falls back to to_string(string), causing an obvious issue. Is there a better way (in which case this isn't an actual bug)?
 
If you are doing comparisons, it was never safe to compare items to strings. Unlike comparing apples to oranges, which always works.

if you just wanted to print out the item, you have to disambiguate it anyway but it'll coerce directly into a string if it is required to do so.
 
If you are doing comparisons, it was never safe to compare items to strings. Unlike comparing apples to oranges, which always works.

if you just wanted to print out the item, you have to disambiguate it anyway but it'll coerce directly into a string if it is required to do so.

Printing is the use-case I had in mind. What do you mean "it'll coerce directly into a string if it's required to do so?" print($item[x]) leaves me with the same prefix, so I don't think you mean "if it's cast implicitly."
 

guyy

Member
If you need to print the name of the item without the number attached, you can just take that part off:

Code:
item the_item = $item[[7302]Spookyraven Library Key];
print(replace_all(create_matcher("^\\[[0-9]+\\]",to_string(the_item)),""));

That "replace_all(create_matcher(" device will remove any bracketed number from the start of a string, so you just get "Spookyraven Library Key."

Adding the number to ambiguous items keeps you from getting the same to_string() result for different items, which is presumably the purpose of it.
 
That "replace_all(create_matcher(" device will remove any bracketed number from the start of a string, so you just get "Spookyraven Library Key."

Adding the number to ambiguous items keeps you from getting the same to_string() result for different items, which is presumably the purpose of it.

Well, sure, I can remove the prefix explicitly, before printing. It just seems odd to me that the string value of an item is disambiguated in that way. When precision comparisons are needed, I'm not typically going to be using string values - I'll be doing "$item[[1764]Spookyraven library key] == item[[7302]Spookyraven library key]", and that will work just fine for its purpose. When I'm printing an item's name, I typically want just its "common name" (unprefixed). Adding the item number to the string value seems to me like asking, "Hey, what's that guy's name?" and getting the answer, "Oh, that's John Doe DOB 03/04/1972 (not to be confused with John Doe DOB 09/12/1980)." It seems awkward to have to ask, instead, "Hey, what's that guy's name, but minus his birthdate?" because what I really want is, simply, his name.

It sounds like there must've already been a discussion where people decided that string values should be unambiguous, and perhaps I'm in the minority of use-cases. It wouldn't be the first time. Thanks for the explanation and work-around.
 

Veracity

Developer
Staff member
It has nothing to do with "precision comparisons".

item oslk = $item[[1764]Spookyraven library key];
item nslk = $item[[7302]Spookyraven library key];

oslk.to_int() -> 1764
nslk.to_int() -> 7302

oslk == nslk -> false

oslk.to_string().to_item() == oslk -> true
nslk.to_string().to_item() == nslk -> true

Those last two are key; you can convert an item to a string and back to an item and get the same item back.

Which is to say that disambiguated names are important for programs to internally manipulate and convert items.

Your use case is to display the item to the user - not the program. You would like the OUTPUT of the item to be potentially ambiguous. One assumes that you are not worried about user INPUT being ambiguous, because ASH only allows that at program startup.

But, lets consider that. Let's use effects, since they also have a variety of duplicate names. Your program takes a string which is an effect name and tells the user what it will do and how to get it. You use a string since, otherwise, you get a drop-down with 2000 some entries in it.

If the user types "Hip to the Jive", is it "drink 1 Hot Socks" and get "Experience (familiar): +2, Familiar Weight: +10, Familiar Damage: +20" or is it "use 1 baloney rotgut" and get "Avatar: "hep cat""?

KoLmafia chooses the last 1 - and says so, after listing both possibilities - and disambiguates to "[1872]Hip to the Jive".

In any case the intent is that

to_item( to_string( item ) ) == item

and

to_string( to_item( string ) ) == string.

I'm curious to hear your ideas about how to achieve this without disambiguating the string representation of ambiguous item names.
 
In any case the intent is that

to_item( to_string( item ) ) == item

and

to_string( to_item( string ) ) == string.

I'm curious to hear your ideas about how to achieve this without disambiguating the string representation of ambiguous item names.

I would not have expected that logic to be true, just as, in my example above, I would not expect to_person_name(to_unambiguous_vital_statistics(person_name)) == unambiguous vital statistics. In cases where I want to be absolutely unambiguous about an item, I would use $item[itemnum] or to_item(itemnum), since I have always thought of an item's string value as it's (potentially-ambiguous) "common name;" ie. the value matching what KoL calls the item when I see it in my inventory. It's evident that my treatment of item names does not match the philosophy of Mafia qua the devs. *shrug* Not a Bug.
 

Veracity

Developer
Staff member
The big reason this was done is that to_string() is used for every field in map_to_file() and to_item( string ), to_skill( string ), and so on is applied to each field, as appropriate, by file_to_map().

Which is to say, as I explained, to_string( item ) and to_item( string) have to be exact inverses of each other.
 

Bale

Minion
Printing is the use-case I had in mind. What do you mean "it'll coerce directly into a string if it's required to do so?" print($item[x]) leaves me with the same prefix, so I don't think you mean "if it's cast implicitly."

Veracity, should the item coerce into a string when used that way? Is there a bug here, or does it need to be done like print( $item[x]+"" ) ?
 

Veracity

Developer
Staff member
print() takes a string. Every object can be coerced into a string. Therefore, every object can be the argument of print().

Similarly, string concatenation via "+" requires two strings - the left-hand-side and the right-hand-side. Since every object can be coerced into a string, again, you can concatenate a string with a non-string just fine. (You do need at least one string, since 1 + 2 is an integer, not the string "1 + 2" - unless used as the argument to something that requires a string, in which case it coerces into "3").

It is not a bug for an item to coerce into string which unambiguously names that item. See my comment about map_to_file().

Perhaps what we have here is a Feature request for an item proxy field. Something like this:

Code:
item it = $item[[1764]Spookyraven library key];
print( it );
print( it.potentially_ambiguous_item_name_that_is_confusingly_found_in_the_game_itself );
yields

Code:
[1764]Spookyraven library key
Spookyraven library key
:)
 
Last edited:

heeheehee

Developer
Staff member
It is not a bug for an item to coerce into string which unambiguously names that item.

Well, maybe the converse is a bug -- $item[rock] unambiguously referred to the Crimbo 2006 (?) crafting component until Spelunky came around, at which point datafiles containing that item disambiguated to the wrong item. Sure, that particular example is probably not very widespread, but it can lead to unexpected changes in datafile behavior.
 

AlbinoRhino

Active member
Hmm...$item[].game_name kind of rolls off of the tongue better. Not as well as potentially_ambiguous_item_name_that_is_confusingly_found_in_the_game_itself though...
 

Veracity

Developer
Staff member
Well, maybe the converse is a bug -- $item[rock] unambiguously referred to the Crimbo 2006 (?) crafting component until Spelunky came around, at which point datafiles containing that item disambiguated to the wrong item. Sure, that particular example is probably not very widespread, but it can lead to unexpected changes in datafile behavior.
That is true. To be completely safe, $item[rock] would have to coerce into [2108].

However, in order to accommodate changes in KoL's database, $item[rock] and a simple "rock" in an item field in a data file both now give warnings, allowing the user to disambiguate them.
 

heeheehee

Developer
Staff member
If we're planning to add a proxy field, why not just "$item[].name"? It's not like we have a field called $item[].kol_internal_id.
 

Veracity

Developer
Staff member
Will this do?

Code:
[color=green]> ash to_item( 7302 ).to_string()[/color]

Returned: [7302]Spookyraven library key

[color=green]> ash to_item( 7302 ).name[/color]

Returned: Spookyraven library key

[color=green]> ash to_item( 69 ).name[/color]

Returned: Newbiesport™ tent

[color=green]> ash to_item( 69 ).name.entity_encode()[/color]

Returned: Newbiesport™ tent

[color=green]> ash to_item( 3465 ).name[/color]

Returned: Bash-Ōs cereal

[color=green]> ash to_item( 3465 ).name.entity_encode()[/color]

Returned: Bash-& #332;s cereal
Note that it returns the actual data name as used by KoL, which the gCLI will render prettily for you, as it is an HTML document. (I added a space to the Unicode entity in that last one because otherwise the forum software turns it into a single Unicode character.)

Revision 17840 adds your implicitly requested FEATURE, rather than fixing the not-a-bug in to_string( item ).

:p
 
Top