codemorphis.com Forum Index codemorphis.com
Software development: pure and simple.
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

String Tokenizer help needed

 
This forum is locked: you cannot post, reply to, or edit topics.   This topic is locked: you cannot edit posts or make replies.    codemorphis.com Forum Index -> Visual Programming Forum
View previous topic :: View next topic  
Author Message
waveterm



Joined: 12 Jan 2005
Posts: 21
Location: Berkeley, CA

PostPosted: Thu Feb 28, 2008 12:58 pm    Post subject: String Tokenizer help needed Reply with quote

I get an Index Out Of Range error with the GetToken method. I can't understand what's going on here. Anyone work this out? I'll attach a sample of the code if someone will tell me how. Thanks
Back to top
View user's profile Send private message
CodeMorphis



Joined: 02 Dec 2003
Posts: 252

PostPosted: Thu Feb 28, 2008 1:27 pm    Post subject: Reply with quote

Can you please send your example to support@codemorphis.com? We'll investigate the problem.

Thanks,

CodeMorphis Support
Back to top
View user's profile Send private message Send e-mail Visit poster's website
waveterm



Joined: 12 Jan 2005
Posts: 21
Location: Berkeley, CA

PostPosted: Thu Feb 28, 2008 2:43 pm    Post subject: Reply with quote

sent
Back to top
View user's profile Send private message
CodeMorphis



Joined: 02 Dec 2003
Posts: 252

PostPosted: Thu Feb 28, 2008 3:45 pm    Post subject: Reply with quote

Hi waveterm,

Thanks for sending in your example program.

The problem is not a bug but rather a misusage or programming error. The error message that you see is provided by Synopsis to help you identify the programming error.

Let’s look at your program:



In data port 0 of the String Tokenizer component named “Str Tok 1” you have supplied the input string to tokenize: “a:b:c:d” along with a separator character “:”. This means that you should have 4 tokens split by the component. So the input string “a:b:c:d” is stored in “Str Tok 1”.

The problem is that you are then using a new String Tokenizer component named “Str Tok 2” to try to retrieve the split tokens. This second component does not contain your input string and hence neither your expected tokens and so when you ask it for the Nth token in your For Loop, it will of course complain that the index is out of bounds since it has 0 tokens.

What you need to do is query “Str Tok 1”, which contains your input string. Note that the String Tokenizer component is an object component, as indicated by the green background. This means that the component maintains its own data in addition to providing one or more services. You can read about object components in the Help module, in Getting Started | Synopsis Components | Object Connections.

The way to interact with an object component and get to its data is via the Service Call component:


Note that we have replaced the component “Str Tok 2” with a Service Call component that refers to the first String Tokenizer component.

This now does what you want – you are passing the token index from the For Loop control into the Service Call component that acts as an interface to the “Str Tok 1” component.

You can download the corrected version of the program here:
http://www.codemorphis.com/articles/ans08/ans_022808/TokenIndex_Corrected.vpd

As an additional note, you have the number of tokens “hard-coded” into data port 1 of the For Loop component, meaning that you edited the port and put the value 4 there. This works fine for the input of your String Tokenized component “a:b:c:d” which has 4 tokens separated by the colon character. But if you were to change the input string to say “a:b:c:d:e” then you would have 5 tokens but your For Loop component still only loops 4 times. A better programming style would be to pass the output of the “Split String” service of the String Tokenizer component to the For Loop:


This way, your program will behave correctly when you change the input string.

Hope that this helps.
Back to top
View user's profile Send private message Send e-mail Visit poster's website
waveterm



Joined: 12 Jan 2005
Posts: 21
Location: Berkeley, CA

PostPosted: Thu Feb 28, 2008 7:59 pm    Post subject: Reply with quote

CodeMorphis wrote:


In data port 0 of the String Tokenizer component named “Str Tok 1” you have supplied the input string to tokenize: “a:b:c:d” along with a separator character “:”. This means that you should have 4 tokens split by the component. So the input string “a:b:c:d” is stored in “Str Tok 1”.

The problem is that you are then using a new String Tokenizer component named “Str Tok 2” to try to retrieve the split tokens. This second component does not contain your input string and hence neither your expected tokens and so when you ask it for the Nth token in your For Loop, it will of course complain that the index is out of bounds since it has 0 tokens.


It will also curiously complain that it is out of bounds if you ask for the zeroth token.



CodeMorphis wrote:

What you need to do is query “Str Tok 1”, which contains your input string. Note that the String Tokenizer component is an object component, as indicated by the green background. This means that the component maintains its own data in addition to providing one or more services. You can read about object components in the Help module, in Getting Started | Synopsis Components | Object Connections.


O.K., I think my confusion has to do with the fact that I was able to create the object component StringTokenizer with the GetToken method. It seems to me that this object cannot be used for anything. That object has no data port for a string to get a token from, so I thought that it must relate to any StringTokenizer at the same nesting level! Does this object actually have a function, or is it some sort of residue from having that method available for use in a service call?


CodeMorphis wrote:

The way to interact with an object component and get to its data is via the Service Call component:


Note that we have replaced the component “Str Tok 2” with a Service Call component that refers to the first String Tokenizer component.

This now does what you want – you are passing the token index from the For Loop control into the Service Call component that acts as an interface to the “Str Tok 1” component.


Got it!

CodeMorphis wrote:

As an additional note, you have the number of tokens “hard-coded” into data port 1 of the For Loop component, meaning that you edited the port and put the value 4 there. This works fine for the input of your String Tokenized component “a:b:c:d” which has 4 tokens separated by the colon character. But if you were to change the input string to say “a:b:c:d:e” then you would have 5 tokens but your For Loop component still only loops 4 times. A better programming style would be to pass the output of the “Split String” service of the String Tokenizer component to the For Loop:


Yeah, it wasn't meant to be pretty or anything Wink Just there to exercise the function a little, because I find it easier to comprehend a function when I see it iterate.


CodeMorphis wrote:

Hope that this helps.


It does! Thanks for the help.
Back to top
View user's profile Send private message
CodeMorphis



Joined: 02 Dec 2003
Posts: 252

PostPosted: Thu Feb 28, 2008 8:18 pm    Post subject: Reply with quote

waveterm,

Quote:
It will also curiously complain that it is out of bounds if you ask for the zeroth token.

That is because the component has no data, thus the message is normal and expected. Recall that the 0th index refers to the first token in the list kept as the indices are zero offsets.


Quote:
O.K., I think my confusion has to do with the fact that I was able to create the object component StringTokenizer with the GetToken method. It seems to me that this object cannot be used for anything. That object has no data port for a string to get a token from, so I thought that it must relate to any StringTokenizer at the same nesting level! Does this object actually have a function, or is it some sort of residue from having that method available for use in a service call?

There is nothing that says that you are required to make the "Split String" service call to the String Tokenizer component first and then use the Service Call component to retrieve the tokens with the "Get Token" service, i.e. you could do the following:



Glad that this has helped you. Understandably, there are some new concepts to grasp but hopefully this all makes sense after the explanation and it helps you to develop/prototype what you need.
Back to top
View user's profile Send private message Send e-mail Visit poster's website
waveterm



Joined: 12 Jan 2005
Posts: 21
Location: Berkeley, CA

PostPosted: Fri Feb 29, 2008 5:46 pm    Post subject: Reply with quote

CodeMorphis wrote:
waveterm,


Quote:
O.K., I think my confusion has to do with the fact that I was able to create the object component StringTokenizer with the GetToken method. It seems to me that this object cannot be used for anything. That object has no data port for a string to get a token from, so I thought that it must relate to any StringTokenizer at the same nesting level! Does this object actually have a function, or is it some sort of residue from having that method available for use in a service call?

There is nothing that says that you are required to make the "Split String" service call to the String Tokenizer component first and then use the Service Call component to retrieve the tokens with the "Get Token" service, i.e. you could do the following:



Glad that this has helped you. Understandably, there are some new concepts to grasp but hopefully this all makes sense after the explanation and it helps you to develop/prototype what you need.


O.K., that helps.

Am I correct in the following understanding of your example?
First you instantiate the Get token object as Str Tok 1 and then you use the service call to the Get token (Str Tok 1) object. This works because the Get token object is initialized before run time and not the first time it is encountered in the chain. Essentially, you have to declare the object by adding it to the project and then you can make service calls. Correct?

I guess it would be cool procedurally if you could add the service call to the project as it appears in the flow and type in the name of the serviced object, thereby declaring it. Then when you come to adding the serviced object to the project, you could select its reference name from a list.
Back to top
View user's profile Send private message
CodeMorphis



Joined: 02 Dec 2003
Posts: 252

PostPosted: Fri Feb 29, 2008 8:58 pm    Post subject: Reply with quote

Quote:
Am I correct in the following understanding of your example?
First you instantiate the Get token object as Str Tok 1 and then you use the service call to the Get token (Str Tok 1) object. This works because the Get token object is initialized before run time and not the first time it is encountered in the chain. Essentially, you have to declare the object by adding it to the project and then you can make service calls. Correct?

I guess it would be cool procedurally if you could add the service call to the project as it appears in the flow and type in the name of the serviced object, thereby declaring it. Then when you come to adding the serviced object to the project, you could select its reference name from a list.

You can do that and you can also do what you asked for.

You can create a Service Call component and name it as desired and connect it in your program. You can then instantiate an object component such as the String Tokenizer component and edit the Service Call component to reference it.

An object component needs to exist in the program before it can be referenced by a Service Call component but it can be called in the program flow after referencing Service Call components.
Back to top
View user's profile Send private message Send e-mail Visit poster's website
Display posts from previous:   
This forum is locked: you cannot post, reply to, or edit topics.   This topic is locked: you cannot edit posts or make replies.    codemorphis.com Forum Index -> Visual Programming Forum All times are GMT - 5 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group