Bug - Fixed or Bug? group(x) returns "0" for empty match

I have a matcher for API that I run line by line, and some lines don't have any data after the " => " part (pieces that go into a new array, for instance)

Code:
  m=create_matcher("\\'?(\\w+)\\'? => (?:\\'?(.+?)\\'?,)?",line);
  if (!m.find())continue;
print(m.group(2));
  if (m.group(2)==""){
   mainArray[cd,m.group(1)]="NARRAY:"+to_string(count(mainArray)+1);
  }else{
   mainArray[cd,m.group(1)]=m.group(2);
  }
 }

I'm fairly certain that the matcher isn't designed wrong, as it works fine on everything, but that print seems to suggest that what should be an empty string is really "0".
 
Code:
array (
  'playerid' => '1453212',
  'name' => 'Almighty Sapling',
  'hardcore' => '1',
  'ascensions' => '44',
  'path' => '4',
  'sign' => 'Vole',
  'roninleft' => '40',
  'casual' => '0',
  'drunk' => '0',
  'turnsplayed' => '148772',
  'familiar' => '91',
  'hp' => '52',
  'mp' => '110',
  'meat' => '28388',
  'adventures' => '36',
  'level' => '11',
  'rawmuscle' => '5532',
  'rawmysticality' => '5469',
  'rawmoxie' => '14344',
  'basemuscle' => '74',
  'basemysticality' => '73',
  'basemoxie' => '119',
  'familiarexp' => 400,
  'class' => '6',
  'lastadv' => 
  array (
    'id' => '123',
    'name' => 'The Arid, Extra-Dry Desert',
    'link' => 'adventure.php?snarfblat=123',
    'container' => 'beach.php',
  ),
  'title' => '11',
  'maxhp' => 106,
  'maxmp' => 153,
  'muscle' => 83,
  'mysticality' => 82,
  'moxie' => 175,
  'famlevel' => 25,
  'equipment' => 
  array (
    'hat' => '538',
    'shirt' => '2127',
    'pants' => '361',
    'weapon' => '5038',
    'offhand' => '2093',
    'acc1' => '3033',
    'acc2' => '5085',
    'acc3' => '1948',
    'fakehands' => 0,
  ),
  'stickers' => 
  array (
    0 => 0,
    1 => 0,
    2 => 0,
  ),
  'flag_config' => 
  array (
    'lazyinventory' => 0,
    'questtracker' => '1',
    'compactchar' => 0,
    'nodevdebug' => 0,
    'noquestnudge' => '1',
    'nocalendar' => 0,
    'alwaystag' => 0,
    'clanlogins' => 0,
    'quickskills' => 0,
    'hprestorers' => 0,
    'hidejacko' => '1',
    'anchorshelf' => '1',
    'showoutfit' => '1',
    'wowbar' => '1',
    'swapfam' => 0,
    'invimages' => 0,
    'showhandedness' => 0,
    'acclinks' => '1',
    'invadvancedsort' => 0,
    'powersort' => '1',
    'autodiscard' => 0,
    'unfamequip' => 0,
    'invclose' => '1',
    'sellstuffugly' => 0,
    'oneclickcraft' => '1',
    'dontscroll' => 0,
    'multisume' => 0,
    'threecolinv' => '1',
    'profanity' => '1',
    'autoattack' => 0,
    'topmenu' => 0,
  ),
  'recalledskills' => 0,
  'freedralph' => 0,
  'mcd' => 0,
  'pwd' => [redacted],
  'rollover' => '1309750200',
  'turnsthisrun' => 960,
  'familiarpic' => 'cccarnie',
  'effects' => 
  array (
  ),
)
After splitting this up by line, and throwing out "array (" and ")" and ")," lines, the rest gets put to the matcher. Everywhere group(2) should be empty, it is returning 0. (like the fourth to last line)
EDIT: and everywhere it isn't empty, it works perfectly fine.
 

Veracity

Developer
Staff member
How odd.

Code:
string line = "  'effects' => ";
matcher m = create_matcher( "\\'?(\\w+)\\'? => (?:\\'?(.+?)\\'?,)?", line );
if ( m.find() )
{
	print( m.group(0) );
	print( m.group(1) );
	print( m.group(2) );
}
yields

> matcher.ash

'effects' =>
effects
0

whereas in my regexp test harness:

Code:
$ java RegexTestHarness

Enter your regex: \'?(\w+)\'? => (?:\'?(.+?)\'?,)?
Enter input string to search:   'effects' => 
I found the text "'effects' => " starting at index 2 and ending at index 15.
group(1) = effects
group(2) = null

Enter your regex:

Looking at group() in the ASH RuntimeLibrary:

Code:
			return new Value( m.group( index ) );
I would guess that Value( null ) returns an int 0, rather than a String.
 

Veracity

Developer
Staff member
It's a bug. Change Value.c from:

Code:
	public Value( final String value )
	{
		this.type = DataTypes.STRING_TYPE;
		this.contentString = value;
	}

to
Code:
	public Value( final String value )
	{
		this.type = DataTypes.STRING_TYPE;
		this.contentString = value == null ? "" : value;
	}

I'll submit it by and by.
 

Bale

Minion
Oh. Thank you. That caused me some trouble in the past, but I assumed that it must be the java implementation and figured out a workaround rather than trouble you with java's regexp code.
 

Veracity

Developer
Staff member
The thing is, in Java, you can tell the difference between returning null and "" - but ASH has no null.
 

heeheehee

Developer
Staff member
Would it be worth a feature request to get a null value in ASH or would that be too much to change?

Depends on how you want null to work. It could be the default value for when you haven't actually assigned a value to a variable and only have provided a forward reference (somewhat like `undefined` of Javascript), or it could be the default value for just Objects (which could be limited to just arrays/maps/records, although this would drastically change the way records are used, and would essentially force constructors into existence. On the other hand, circular structures would be viable...).

The main issue is that the vast majority of uses of records *will* break, since most ASH scripters don't use `new`, I'd imagine.
 

Bale

Minion
You broke my alias!

PHP:
alias pref => ashq record r{string d;};r[string,string] m; string[int]a; file_to_map("defaults.txt",m); matcher s = create_matcher("(\\w+)(\\s=*\\s*([\\w\\.]+))?",$string[%%]); if(find(s)){foreach t,p,d in m if(to_lower_case(p).contains_text(to_lower_case(s.group(1)))) {print(p+" ("+t+", now '"+get_property(p)+"', default "+d.d+")"); a[count(a)] = p;}if(s.group(2)!="0"){if(count(a)==1)set_property(a[0],s.group(3));else print("You do not match exactly one preference!","red");}}else print("Invalid parameters","red");

Replaced "0" with "" and all is good now, but I was rather surprised when a trusted alias started doing something bad to me.
 
Last edited:

Bale

Minion
Yes, there's a "0" in that code. You didn't look at it because you assumed it was identical to a similar alias you use. Mine can also set the preferences if I only type part of the preference name and use all lower case letters. It's just easier for me to combine that improved set command into the same alias.

Unfortunately this bugfix caused my alias to clear any single preference I matched, even if I didn't intend to change it. Oops.
 
Last edited:

Winterbay

Active member
Ahh no, the problem was that the box is so small that I thought it was only two lines of code while it was in fact a lot more than that. Found the 0 :)
 
Top