Can Coldfusion determine the type of an array in a function argument?

Inside the ColdFusion component, I declare this function:

string function render(required Array actions) output=false { //... } 

Thus, a function parameter can only accept an array. However, I need to make sure that the array contains only ActionItem objects (there is an ActionItem.cfc component)

Is there a way in ColdFusion for a type to hint at the contents of an array? What solution do you propose in this case?

+4
source share
4 answers

In short, as Peter said in his commentary, the main answer is "you cannot." ColdFusion has no concept of array types.

There are two ways. First, brute force approach to check each element of the array as necessary to make sure you need it. This is what Peter offers, and generally what I will do.

Otherwise, you can implement ActionItemCollection.cfc , which itself contains an array of ActionItems , and leave it ActionItemCollection.cfc only for accepting ActionItem objects, so by the time your render() function gets its ActionItemCollection >, it "knows" that each item in the collection is definitely an ActionItem .

This suggests that there might be a lot of work when you could just get render() to check if the element is legitimate and throw an exception if not. This is not an ideal solution, but CF creates an imperfect situation, so fair.

+4
source

To talk about my comment, below is a diagram of a possible collection that you could create.

I like collection classes, and the ArrayCollection class is very reused here and allows you to use a wrapped array as an object.

  component ArrayCollection() { public function init() { variables.collection = []; return this; } public any function get(); public function set(required array collection); public function add(required any item); public function remove(); } component ActionItemCollection extends ArrayCollection { public function add(required ActionItem item); public ActionItem function get(); } component otherComponnet{ public string function render(required ActionItemCollection actions) { } } 

In some cases this may be redundant, but it allows you to specify the type of elements in the array!

+4
source

In fact, ColdFusion supports some support for validation type arrays (which should not be confused with typed arrays), but it only works with custom components not for primitive types . However, I did not find any other documentation for this feature other than this blog post .

Suppose we have a SomeObject component.

We could write:

 <cffunction name="testArrayTypeValidation"> <cfargument name="someObjects" type="SomeObject[]" required="yes"> <cfdump var="#someObjects#"> </cffunction> 

And then call our function as follows:

 <cfset testArrayTypeValidation([new SomeObject()])> 

However, be careful that it will only check the type of the first element in the array, which means the following will also work:

  <cfset testArrayTypeValidation([new SomeObject(), 'some string'])> 

In addition, it does not work for primitive types, so you cannot use type="string[]" , for example, which is sad.

For primitive types, you will have to implement your own specific wrapper class that will contain only primitives of a certain type and use this class as an argument type.

+3
source

You can write a function to check the array. This will require 2 arguments, your array to check and the type of the object and return a boolean result. The function will loop through the object and determine if the value in this index is an object, and if so, look at the metadata to determine if it is the type you want. The first time you find a bad item, you set a false return value and break the loop. This is not the most ideal solution, but it will work and be universal so that you can use it as a check in any of your other components.

Also, just for your own sanity, I will definitely refer to everything as you expect:

public model.bean.Foo[] function Read(required model.bean.Foo aBean) {...}

Thus, the function expects the Foo object as an argument and returns an array of Foo objects. Just make sure you add the mapping to the starting point of the path (the β€œmodel” in my case), so CF will know where to start looking for it. In Application.cfc add something like:

this.mappings["/model"] = getDirectoryFromPath(expandPath(".")) & "myProjectDir/model";

0
source

Source: https://habr.com/ru/post/1491647/


All Articles