• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

can someone explain, and/or justify this?

New Here ,
Mar 10, 2015 Mar 10, 2015

Copy link to clipboard

Copied

     x=app.activeDocument.viewPreferences.horizontalMeasurementUnits

     Result: PICAS

// so far, so good.  Just to be sure...

     x.toString()

     Result: PICAS

// now

     x+x

     Result: 4108374726

// huh?

     x+x.toString()

    Result: 2054187363PICAS

// and finally

    "units are "+x

    Result: units are 2054187363

I suppose there's some explanation why the measurement units for picas is secretly associated

with the integer 2054187363 and why it's a good idea.

TOPICS
Scripting

Views

1.1K

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Guide , Mar 12, 2015 Mar 12, 2015

Hi all,

Here are additional details on Enumeration and Enumerator objects in CS5 and later:

http://www.indiscripts.com/post/2012/07/indesign-scripting-forum-roundup-3#hd1sb1

@+

Marc

Votes

Translate

Translate
People's Champ ,
Mar 10, 2015 Mar 10, 2015

Copy link to clipboard

Copied

The answer is simply that MeasurementUnits is an enumerator. So really

the fundamental value of each particular MeasurementUnit is an integer,

as is the case for any enumerator.

When you write x = myDoc.viewPreferences.horizontalMeasurementUnits,

InDesign is actually doing you a favour in that it returns something

comprehensible (PICAS, CM, etc.). In fact, if I recall correctly, in

older versions (CS4), you'd only ever get the enum value.

So in fact it is possible to write:

myDoc.viewPreferences.horizontalMeasurementUnits = 2053335395 and it

will be set to Ciceros, in this case. (All the numbers are listed in the

OMV in ESTK).

If you write:

app.viewPreferences.horizontalMeasurementUnits.valueOf()

You'll get the actual enumerator number.

However, because Javascript is freely typed, it will helpfully convert

something to a string if you alert() it, or display it in the Console, etc.

So, as per your examples: if you add two enumerators, the interpreter

does not do a toString(), hence you get an integer.

If you add an enum to a string (as in the second example), it's like

adding any number to a string: 5+"z" will give: 5z.

In the last example, the enum remains an integer.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Mar 10, 2015 Mar 10, 2015

Copy link to clipboard

Copied

This almost makes sense, but the behavior of the enumerator object

is odd with respect to the + operator.  What is the point of giving an

enum any meaning as an integer at all?

for most objects,  object+object becomes object.toString()+object.toString(),

so what magic causes this enumerator to be interpreted as an integer, and why is that desirable?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
People's Champ ,
Mar 11, 2015 Mar 11, 2015

Copy link to clipboard

Copied

That's just what an enumerator is: "An enumeration consists of a set of

named integer constants."

It's a convenient way of referring to a number with a more memorable

name. But the underlying value of any element in an enumerator is an

integer.

There's nothing surprising about this.

Note that:

MeasurementUnits.INCHES === 2053729891

returns true.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Mar 11, 2015 Mar 11, 2015

Copy link to clipboard

Copied

these enums are not integers, they are objects.  Somewhere in the bowels of their

behavior, unlike most objects, they respond to + as an integer rather than as a string.

My guess is that adobe engineers, when they were adapting existing internals to a javascript interface,

found that then needed to do range checks on measurement units (ie; existing C code was something

like)

  enum measurementunit { picas=1, points=2, inches=3 }

and code existed that did things like

  if(units>points) {}

and for whatever reason, they decided this semantics needed to be visible to the javascript binding.  It's a crappy

reason, but at least it's a reason.

---

Final watchword on the subject - these objects are complete liars.  Try this:

var x = MeasurementUnits.picas;

var y = 2054187363;

var z = "2054187363";

typeof x is object

typeof y is number

typeof z is string

x==y  is true

x===y is also true !

x===z is also true !

y===z is false (as expected)

so we've broken a basic identity - these enums are identical to many things that are not identical to each other.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
Mar 12, 2015 Mar 12, 2015

Copy link to clipboard

Copied

Hi all,

Here are additional details on Enumeration and Enumerator objects in CS5 and later:

http://www.indiscripts.com/post/2012/07/indesign-scripting-forum-roundup-3#hd1sb1

@+

Marc

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advisor ,
Mar 11, 2015 Mar 11, 2015

Copy link to clipboard

Copied

Enumerators do not call .toString() automatically. Why is that, i have no idea, but i agree it is bad, and can lead to very strange behaviour.

Your MeasurmentUnits example is just the tip of the iceberg. Worst culprits are the SpecialCharacters enumerator and the worst of the worst: NothingEnum.NOTHING that gets returned in some cases. The big problem with NOTHING is that, when converted it gets evaluated to True, even if it is a considered a falsy value. Even "better", the same member, on different objects will sometimes return Nothing and other times will return null, for example text.appliedCharaterStyle will return null, but findTextPreferences.appliedCharacterStyle willl return NothingEnum.NOTHING

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Mar 12, 2015 Mar 12, 2015

Copy link to clipboard

Copied

While this does seem to describe the behavior of MeasurementUnit.picas, it still doesn't make sense

that "picas" and friends should have these I'm-also-a-number behaviors that do make sense for special

characters.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
Mar 12, 2015 Mar 12, 2015

Copy link to clipboard

Copied

> it still doesn't make sense that "picas" and friends should have these

> I'm-also-a-number behaviors that do make sense for special characters

The I'm-also-a-number behavior does not actually make sense whatever the enum you consider, it's just the way those objects work.

Note, however, that Enumerator instances do not have the cast Number (the typeof operator does return 'object'). What has been done when introducing these objects in CS5 is:

1. Making myEnum.valueOf() return a Number.

2. Overriding == and === so that myEnum can match a Number in both equal and strict-equal comparisons.

The reason for this, IMHO, was to preserve compatibility with previous versions (CS4 and before) where Enumerations—the collection of enums—were just pointing out to numeric values, that is, Numbers.

Thus, a syntax like (myUnit===MeasurementUnits.INCHES), or (myUnit===2053729891), or even (MeasurementUnits.INCHES===2053729891), still works from CS4 to CS5 without breaking existing code.

Now, about the meaning of these numbers, we know they are nothing but unique identifiers. Technically—and this is an old tradition in Adobe architecture—such identifiers are all built based on 4-character sequences.

In the case of measurement units, identifiers are formed using the prefix 'z' and 3 relevant letters from the unit name, usually the leading letters, e.g. 'zinc' for inches, 'zpic' for picas, and so on.

Then, ASCII codes of these characters are taken to build a number:

INCHES => z i n c => 7A 69 6E 63 => 0x7A696E63 (=2053729891 in decimal)

PICAS => z p i c => 7A 70 69 63 => 0x7A706963 (=2054187363 in decimal)

etc.

And you will check that +MeasurementUnits.INCHES is 0x7A696E63.

Anyway, your comment #5 highlights something else, based on the code:

var x = MeasurementUnits.picas;

var y = 2054187363;

var z = "2054187363";

We have checked, indeed, that x===y is true (see reason 2 above).

But we also can check, as you mention, that x===z is true!!! Which is not CS4-backwards-compatible at all and sounds highly irrelevant since x.toString()==='PICAS'.

I suspect that this strange case is a side effect of how the === operator has been overloaded. In my opinion, the hidden function Enumerator['==='](arg) mutely coerces the argument into a Number whatever it actually is. So the string z is simply taken as +z and that's why x===z also returns true. What Adobe should have done instead is:

// JS pseudo code

Enumerator['==='] = function(arg){ return 'string'==typeof arg ? this.toString()==arg : this.valueOf()==+arg };

…and then x===z would have been false, and x==='PICAS' would have been true 😉

@+

Marc

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
People's Champ ,
Mar 12, 2015 Mar 12, 2015

Copy link to clipboard

Copied

Great explanation, Marc!

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Mar 12, 2015 Mar 12, 2015

Copy link to clipboard

Copied

LATEST

I guess we've reached the point of exhaustion on this.  All I really wanted was, when packaging a rectangle

object to also display the units, I was shocked that defining the

   toString() { return("left+","+right+" "+width+"x"+height+" "+units) }

printed a random looking number as the units.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines