问:
How to remove a ViewController from navigation stack and not have the option to go back to it-Swift
I have a Login page and if the login is successful the user is taken to a landing viewController(VC).  I have a navigationController.  I pop the login VC and push in the landing VC.  The problem I am having is that the login VC persists in the stack as indicated by the left button on the navigation controller which navigates you back to the login page.  How do I remove the login VC copletely from the stack so that the navigation controller can not navigate a user back to it once they have logged in?</p>

```<code> self.navigationController?.popViewController(animated: true)

 let landingPage = self.storyboard?.instantiateViewController(withIdentifier: "landingPage") as!
 LandingViewController

 self.navigationController?.pushViewController(landingPage, animated: true)
</code>```

答:
You can use the setViewControllers method to set the stack like this:

```<code>self.navigationController?.setViewControllers([landingPage], animated: true)
</code>```

You don't need to pop the login view controller first either.

Body:
I have a Login page and if the login is successful the user is taken to a landing viewController(VC).  I have a navigationController.  I pop the login VC and push in the landing VC.  The problem I am having is that the login VC persists in the stack as indicated by the left button on the navigation controller which navigates you back to the login page.  How do I remove the login VC copletely from the stack so that the navigation controller can not navigate a user back to it once they have logged in?

 self.navigationController?.popViewController(animated: true)

 let landingPage = self.storyboard?.instantiateViewController(withIdentifier: "landingPage") as!
 LandingViewController

 self.navigationController?.pushViewController(landingPage, animated: true)

Body:
You can use the setViewControllers method to set the stack like this:

self.navigationController?.setViewControllers([landingPage], animated: true)

You don't need to pop the login view controller first either.


来源: stackexchange

问:
android:windowSoftInputMode="adjustResize" when i've already have ScrollView in the activity
I have an activity with this Layouts structure:
LinearLayout -> ScrollView -> TableLayout

Below the TableLayout i have EditText, which I want to be scrolled up when the keyboard is active.
So according to some reading I've made, i added:

```<code>android:windowSoftInputMode="adjustResize"
</code>```

to AndroidManifest.xml, to the relevant activity, and added a ScrollView wrapper to the activity.xml file, so the Layouts structures of the activity is now as follows:
ScrollView -> LinearLayout -> ScrollView -> TableLayout

The problem: The inner ScrollView is not working now... I guess the wrapping ScrollView is taking control when touched...

How can i solve this issue?

Any help will be appreciated.
Thanks.

答:
I was facing the same problem where the virtual keyboard was hiding EditTexts on my screen.
I introduced the following property for activity tag in the manifest file:

```<code> android:windowSoftInputMode="stateVisible|adjustResize|adjustPan"
</code>```

Also I needed to add following code in the activity's OnCreate function:

```<code>this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
</code>```

This solved the problem and it worked perfectly fine on all resolution emulators and samsung devices. It did fail, though, on Google Nexus S device and I could see the same problem again of virtual keyboard hiding the EditTexts.

ContentLicense: CC BY-SA 2.5

Body:
I have an activity with this Layouts structure:
LinearLayout -> ScrollView -> TableLayout

Below the TableLayout i have EditText, which I want to be scrolled up when the keyboard is active.
So according to some reading I've made, i added:

android:windowSoftInputMode="adjustResize"

to AndroidManifest.xml, to the relevant activity, and added a ScrollView wrapper to the activity.xml file, so the Layouts structures of the activity is now as follows:
ScrollView -> LinearLayout -> ScrollView -> TableLayout

The problem: The inner ScrollView is not working now... I guess the wrapping ScrollView is taking control when touched...

How can i solve this issue?

Any help will be appreciated.
Thanks.

Body:
I was facing the same problem where the virtual keyboard was hiding EditTexts on my screen.
I introduced the following property for activity tag in the manifest file:

 android:windowSoftInputMode="stateVisible|adjustResize|adjustPan"

Also I needed to add following code in the activity's OnCreate function:

this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);

This solved the problem and it worked perfectly fine on all resolution emulators and samsung devices. It did fail, though, on Google Nexus S device and I could see the same problem again of virtual keyboard hiding the EditTexts.

ContentLicense: CC BY-SA 3.0


问:
Returning data after sorting through multiple arrays
I have nested arrays within an object, and I need to extract these values, and sort them into alphabetical order which will then be displayed in a table.

I am using the localeCompare method but it is returning:

```<code>Cannot read property 'localeCompare' of null
</code>```

To be honest, I am not sure I am approaching this correctly. Using sort you can compare a to b to sort them into alphabetical order. I am getting confused how to compare the values from the arrays within a and b. I am using the first sort on tableData to access the array, and the using a second sort to compare the values that I pushed to array clientRefArr

```<code>if(params.sorting().clientRef) {

        var clientRefArr = [];

        tableData.sort(function(a, b){

            a.renewalUIs.forEach(function(data, i){
                clientRefArr.push(data.patentUI.clientRef);
            })

            return clientRefArr.sort(function(a, b){
                console.log(a.localeCompare(b))
                // return a.localeCompare(b)
            })

        })

    orderedData = tableData;

}

return orderedData;
</code>```

Question

Why is the error Cannot read property 'localeCompare' of null being returned?Am I approaching this issue completely wrong?

```<code>//JSON

[
 0: {
     transRef: "IX1000013"
     renewalProgress: 30
     renewalUIs: [
        0: {
            patentUI: {
               business: null
               clientRef: P0101011 // this is the required value
            }
            renewalAttemptsMade: 1
            renewalDueDate: 1514764740000
         }
     ]

   },
 1: {
     transRef: "IX100333"
     renewalProgress: 55
     renewalUIs: [
        0: {
            patentUI: {
               business: null
               clientRef: P0101011 // this is the required value
            }
            renewalAttemptsMade: 1
            renewalDueDate: 1514764740000
         },
        1: {
            patentUI: {
               business: null
               clientRef: P5551011 // this is the required value
            }
            renewalAttemptsMade: 3
            renewalDueDate: 174834740000
         }
     ]

   }
]
</code>```

答:
IF my interpretation is correct, it'd be way easier to first put everything in an single array and then sort it as such just use loops for the first task and a normal sort for the second, nested sorts are really just a bad idea.

```<code>// let's assume your data is in unorderedData
var clientUIs = [];
for (var i = 0; i < unorderedData.length; i++){
  for (var j = 0 ; j < unorderedData[i]["renewalUIs"].length; j++){
     // add each UI to your list individually.
     clientUIs.push(unorderedData[i]["renewalUIs"][j]["patentUI"]);
  }
}
clientUIs.sort() //just sort everything
tableData = clientUIs;
</code>```

If "renewalUIs" or "patentUIs" arent constant you can iterate over the keys of the dictionary.

Body:
I have nested arrays within an object, and I need to extract these values, and sort them into alphabetical order which will then be displayed in a table.

I am using the localeCompare method but it is returning:

Cannot read property 'localeCompare' of null

To be honest, I am not sure I am approaching this correctly. Using sort you can compare a to b to sort them into alphabetical order. I am getting confused how to compare the values from the arrays within a and b. I am using the first sort on tableData to access the array, and the using a second sort to compare the values that I pushed to array clientRefArr

if(params.sorting().clientRef) {

        var clientRefArr = [];

        tableData.sort(function(a, b){

            a.renewalUIs.forEach(function(data, i){
                clientRefArr.push(data.patentUI.clientRef);
            })

            return clientRefArr.sort(function(a, b){
                console.log(a.localeCompare(b))
                // return a.localeCompare(b)
            })

        })

    orderedData = tableData;

}

return orderedData;

Question

Why is the error Cannot read property 'localeCompare' of null being returned?Am I approaching this issue completely wrong?

//JSON

[
 0: {
     transRef: "IX1000013"
     renewalProgress: 30
     renewalUIs: [
        0: {
            patentUI: {
               business: null
               clientRef: P0101011 // this is the required value
            }
            renewalAttemptsMade: 1
            renewalDueDate: 1514764740000
         }
     ]

   },
 1: {
     transRef: "IX100333"
     renewalProgress: 55
     renewalUIs: [
        0: {
            patentUI: {
               business: null
               clientRef: P0101011 // this is the required value
            }
            renewalAttemptsMade: 1
            renewalDueDate: 1514764740000
         },
        1: {
            patentUI: {
               business: null
               clientRef: P5551011 // this is the required value
            }
            renewalAttemptsMade: 3
            renewalDueDate: 174834740000
         }
     ]

   }
]

Body:
IF my interpretation is correct, it'd be way easier to first put everything in an single array and then sort it as such just use loops for the first task and a normal sort for the second, nested sorts are really just a bad idea.

// let's assume your data is in unorderedData
var clientUIs = [];
for (var i = 0; i < unorderedData.length; i++){
  for (var j = 0 ; j < unorderedData[i]["renewalUIs"].length; j++){
     // add each UI to your list individually.
     clientUIs.push(unorderedData[i]["renewalUIs"][j]["patentUI"]);
  }
}
clientUIs.sort() //just sort everything
tableData = clientUIs;

If "renewalUIs" or "patentUIs" arent constant you can iterate over the keys of the dictionary.


问:
leaflet coordinates not working
Leaflet Maps Images

KML:

```<code><?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://earth.google.com/kml/2.2">
<Document>

<Placemark>
  <name>10 Downing Street</name>
  <description>Test</description>
  <Point>
    <coordinates>45.7251809,-75.0467511,0</coordinates>
  </Point>
</Placemark>

</Document>
</kml>
</code>```

Why the point is not showing at the exact LAT/LONG, it show on top of the leaflet map...

Google map show the correct lat Google Maps

答:
I just figured that Leaflet KML coordinates is LNG, LAT and not LAT, LNG

Switching coordinates made it all work

Title: leaflet coordinates not working

Body:
Leaflet Maps Images

KML:

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://earth.google.com/kml/2.2">
<Document>

<Placemark>
  <name>10 Downing Street</name>
  <description>Test</description>
  <Point>
    <coordinates>45.7251809,-75.0467511,0</coordinates>
  </Point>
</Placemark>

</Document>
</kml>

Why the point is not showing at the exact LAT/LONG, it show on top of the leaflet map...

Google map show the correct lat Google Maps


问:
Combining two images into one
I need to take two images (given through URL inputs) and output something that looks like this:

I'm using Jimp to generate the image. This should be a relatively simple thing to do with a mask. For my project, I cannot use the canvas so if you have examples, try to not include the DOM. This is what i'm going for:

```<code>const jimp = require("jimp")
const split = (url1, url2) => {
    jimp.read(url1, (err, image) => {
    //mask
    //paste image from url2
    //return new image
    })
}
</code>```

答:
jimp has a mask() function. Actually, this will give you the diagonal that you want:

```<code>"use strict";

const Jimp = require("jimp"),
    util = require("util");

const jreadAsync = util.promisify(Jimp.read),
    jwriteAsync = util.promisify(Jimp.prototype.write);

const filesToRead = [
    "https://www.example.com/image1",
    "https://www.example.com/image2"
];

Promise
    .all(filesToRead.map(img => jreadAsync(img)))
    .then((res) => {
        let [
            image1,
            image2
        ] = res;

        image1.scan(0, 0, image1.bitmap.width, image1.bitmap.height, (x, y, idx) => {
            if ((image1.bitmap.width - x) > y) {
                return;
            }
            image1.setPixelColor(image2.getPixelColor(x, y), x, y);
        });
        return jwriteAsync.call(image1, `out.${image1.getExtension()}`);
    })
    .catch(console.error);
</code>```

This is using the images from Gabriel Ambrósio Archanjo's answer:

Title: Combining two images into one

Body:
I need to take two images (given through URL inputs) and output something that looks like this:

I'm using Jimp to generate the image. This should be a relatively simple thing to do with a mask. For my project, I cannot use the canvas so if you have examples, try to not include the DOM. This is what i'm going for:

const jimp = require("jimp")
const split = (url1, url2) => {
    jimp.read(url1, (err, image) => {
    //mask
    //paste image from url2
    //return new image
    })
}

Body:
jimp has a mask() function. Actually, this will give you the diagonal that you want:

"use strict";

const Jimp = require("jimp"),
    util = require("util");

const jreadAsync = util.promisify(Jimp.read),
    jwriteAsync = util.promisify(Jimp.prototype.write);

const filesToRead = [
    "https://www.example.com/image1",
    "https://www.example.com/image2"
];

Promise
    .all(filesToRead.map(img => jreadAsync(img)))
    .then((res) => {
        let [
            image1,
            image2
        ] = res;

        image1.scan(0, 0, image1.bitmap.width, image1.bitmap.height, (x, y, idx) => {
            if ((image1.bitmap.width - x) > y) {
                return;
            }
            image1.setPixelColor(image2.getPixelColor(x, y), x, y);
        });
        return jwriteAsync.call(image1, `out.${image1.getExtension()}`);
    })
    .catch(console.error);

This is using the images from Gabriel Ambrósio Archanjo's answer:


问:
Could not commit JPA transaction: Transaction marked as rollbackOnly
I'm using Spring and Hibernate in one of the applications that I'm working on and I've got a problem with handling of transactions.

I've got a service class that loads some entities from the database, modifies some of their values and then (when everything is valid) commits these changes to the database. If the new values are invalid (which I can only check after setting them) I do not want to persist the changes. To prevent Spring/Hibernate from saving the changes I throw an exception in the method. This however results in the following error:

```<code>Could not commit JPA transaction: Transaction marked as rollbackOnly
</code>```

And this is the service:

```<code>@Service
class MyService {

  @Transactional(rollbackFor = MyCustomException.class)
  public void doSth() throws MyCustomException {
    //load entities from database
    //modify some of their values
    //check if they are valid
    if(invalid) { //if they arent valid, throw an exception
      throw new MyCustomException();
    }

  }
}
</code>```

And this is how I invoke it:

```<code>class ServiceUser {
  @Autowired
  private MyService myService;

  public void method() {
    try {
      myService.doSth();
    } catch (MyCustomException e) {
      // ...
    }
  }
}
</code>```

What I'd expect to happen: No changes to the database and no exception visible to the user.

What happens: No changes to the database but the app crashes with:

```<code>org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction;
nested exception is javax.persistence.RollbackException: Transaction marked as rollbackOnly
</code>```

It's correctly setting the transaction to rollbackOnly but why is the rollback crashing with an exception?

答:
As explained @Yaroslav Stavnichiy if a service is marked as transactional spring tries to handle transaction itself. If any exception occurs then a rollback operation performed. If in your scenario ServiceUser.method() is not performing any transactional operation you can use @Transactional.TxType annotation. 'NEVER' option is used to manage that method outside transactional context.

Transactional.TxType reference doc is here.

Body:
I'm using Spring and Hibernate in one of the applications that I'm working on and I've got a problem with handling of transactions.

I've got a service class that loads some entities from the database, modifies some of their values and then (when everything is valid) commits these changes to the database. If the new values are invalid (which I can only check after setting them) I do not want to persist the changes. To prevent Spring/Hibernate from saving the changes I throw an exception in the method. This however results in the following error:

Could not commit JPA transaction: Transaction marked as rollbackOnly

And this is the service:

@Service
class MyService {

  @Transactional(rollbackFor = MyCustomException.class)
  public void doSth() throws MyCustomException {
    //load entities from database
    //modify some of their values
    //check if they are valid
    if(invalid) { //if they arent valid, throw an exception
      throw new MyCustomException();
    }

  }
}

And this is how I invoke it:

class ServiceUser {
  @Autowired
  private MyService myService;

  public void method() {
    try {
      myService.doSth();
    } catch (MyCustomException e) {
      // ...
    }
  }
}

What I'd expect to happen: No changes to the database and no exception visible to the user.

What happens: No changes to the database but the app crashes with:

org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction;
nested exception is javax.persistence.RollbackException: Transaction marked as rollbackOnly

It's correctly setting the transaction to rollbackOnly but why is the rollback crashing with an exception?


问:
java ee - authenticate users using servlets
I just started learning java, and have not worked with java ee. I need to authenticate users using servlets. Advise, please, sample code and technical literature. Thank you!</p>

答: Very simple Servlet/JSP related code to get you started. And here is a fine example of Form Based Authentication Using Servlet.</p>


问:
POST list of objects in rails. How can I whitelist the list of objects in strong params?
I'm trying to post a list of objects called tasks that looks like the following.

```<code>{
  // Shared attributes
  "parent_id": "1",
  "author": "Name Name",
  // Task list
  "tasks": [
   {"name":"task 1"},
   {"name":"task 2"}...
  ]
}
</code>```

In my controller, I have the following, which iterates through tasks, appends the shared attributes, and creates a new Task object:

```<code>task_params[:tasks].each do |task|
      new_params = task
      new_params[:parent_id] = task_params[:parent_id]
      new_params[:author] = task_params[:author]

      new_task = Task.new(new_params)
end
</code>```

The problem is that :tasks isn't showing up in my task_params despite being passed in as a parameter. This seems to be because it isn't whitelisted in strong_params, but that doesn't seem to make a difference. It looks to me like I can only whitelist parameters that correspond to attr_accessors. So how can I pass in the custom parameter tasks through strong_params and into the controller method?

Edit:

My params definition:

```<code>def task_params
     params.require(:task).permit(:parent_id, :author, tasks: [:name])
end
</code>```

Rails output:

```<code>  Parameters: {"parent_id"=>1, "author"=> "Name name", "tasks"=>[{"name"=>"task 1"}, {"name"=>"task 2"}], "task"=>{"job_id"=>1, "author"=>"Name name"}}
</code>```

But when I print the task params in the controller:

```<code>{"parent_id"=>1, "author"=>"Name name"}
</code>```

答:
Are the tasks associated to one another in the model (might be worth copying that code into the question)? If so, do you just need to use accepts_nested_attributes_for?

Docs are here: http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html#method-i-accepts_nested_attributes_for

That way, by adding accepts_nested_attributes_for :tasks (or however you're naming the association) and using fields_for in the form, you should be able to access task data in the params (it'll still need permitting).

Put simply, from the docs:

Defines an attributes writer for the specified association(s).

If you're using the stringified task data, you can probably use an attr_reader in the model to allow this to be passed in the params.

This help?

Body:
I'm trying to post a list of objects called tasks that looks like the following.

{
  // Shared attributes
  "parent_id": "1",
  "author": "Name Name",
  // Task list
  "tasks": [
   {"name":"task 1"},
   {"name":"task 2"}...
  ]
}

In my controller, I have the following, which iterates through tasks, appends the shared attributes, and creates a new Task object:

task_params[:tasks].each do |task|
      new_params = task
      new_params[:parent_id] = task_params[:parent_id]
      new_params[:author] = task_params[:author]

      new_task = Task.new(new_params)
end

The problem is that :tasks isn't showing up in my task_params despite being passed in as a parameter. This seems to be because it isn't whitelisted in strong_params, but that doesn't seem to make a difference. It looks to me like I can only whitelist parameters that correspond to attr_accessors. So how can I pass in the custom parameter tasks through strong_params and into the controller method?

Edit:

My params definition:

def task_params
     params.require(:task).permit(:parent_id, :author, tasks: [:name])
end

Rails output:

  Parameters: {"parent_id"=>1, "author"=> "Name name", "tasks"=>[{"name"=>"task 1"}, {"name"=>"task 2"}], "task"=>{"job_id"=>1, "author"=>"Name name"}}

But when I print the task params in the controller:

{"parent_id"=>1, "author"=>"Name name"}


问:
DataGridView Index was out of range. Must be non-negative
I got a DataGridView in my win form and i am using cell click event to get the value of Ticket Number from the selected to perform deletion everything works fine but when i click on column header:

i get this error

System.ArgumentOutOfRangeException: 'Index was out of range. Must be non-negative and less than the size of the collection.
  Parameter name: index'
  [![enter image description here][2]][2]

I get this error because in cell click event:

```<code>private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
    {
        int indexRow = e.RowIndex;
        DataGridViewRow row = dataGridView1.Rows[indexRow]; //Debugger shows error here
        txtDelete.Text = row.Cells[0].Value.ToString();
    }
</code>```

So i need help in patching/fixing this little bug.
I am using RowIndex of selected cell

答:
In cell click event i was getting indexRow=-1 so i changed the code to:</p>

```<code>private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
    {
        int indexRow = e.RowIndex;
        if (indexRow>=0)
        {
            DataGridViewRow row = dataGridView1.Rows[indexRow];
            txtDelete.Text = row.Cells[0].Value.ToString();
        }

    }
</code>```

Body:
I got a DataGridView in my win form and i am using cell click event to get the value of Ticket Number from the selected to perform deletion everything works fine but when i click on column header:

i get this error

System.ArgumentOutOfRangeException: 'Index was out of range. Must be non-negative and less than the size of the collection.
  Parameter name: index'
  [![enter image description here][2]][2]

I get this error because in cell click event:

private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
    {
        int indexRow = e.RowIndex;
        DataGridViewRow row = dataGridView1.Rows[indexRow]; //Debugger shows error here
        txtDelete.Text = row.Cells[0].Value.ToString();
    }

So i need help in patching/fixing this little bug.
I am using RowIndex of selected cell

Body:
In cell click event i was getting indexRow=-1 so i changed the code to:

private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
    {
        int indexRow = e.RowIndex;
        if (indexRow>=0)
        {
            DataGridViewRow row = dataGridView1.Rows[indexRow];
            txtDelete.Text = row.Cells[0].Value.ToString();
        }

    }


问:
How can i use iPhone's accelerometer in our project?
I want to create simple application on iphone. For this purpose i use accelerometer, my object is on the track and whenever it will go outside the track, it will detect if i moved iphone</p>

答: See the UIAccelerometer class reference. There's sample code as well (see the Related sample code section near the top).


问:
Get the parameter values of the stored procedure dynamically
I am creating sort of auditing functionality for all of my stored procedures. I am able to fetch the name of the parameters that stored procedure has(from : information_schema.parameters table).
However, I would like to create generic code for all stored procedures that would fetch the name of the parameters and correspondingly get the value of those parameters for that invocation and log into another table.

e.g.

```<code>DELIMITER $$
CREATE DEFINER=`root`@`localhost` PROCEDURE `TestSP`(IN `name` VARCHAR(255), IN `userid` INT(255), IN `isnew` VARCHAR(11))
BEGIN

#DECLARE exit handler for sqlexception  ROLLBACK;
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
ROLLBACK;

INSERT INTO app_db_log(TYPE,MESSAGE, INFO) VALUES ('ERROR','An error has occurred, operation rollback and the stored procedure was terminated',<INSERT ALL THE PARAMETER VALUES AS SINGLE STRING HERE> );
COMMIT;

SELECT 'An error has occurred, operation rollback and the stored procedure was terminated';
END;

START TRANSACTION;
SIGNAL SQLSTATE '45000';
COMMIT;
END$$
DELIMITER ;
</code>```

Thanks in advance!

答:
You can get the list of parameters for the routine from INFORMATION_SCHEMA.PARAMETERS, but you'd have to know the schema and name of the procedure:

```<code>mysql> delimiter $$

mysql> create procedure myproc (in foo int, in bar int)
    -> begin
    -> select group_concat(parameter_name order by ordinal_position) as params
    -> from INFORMATION_SCHEMA.PARAMETERS
    -> where specific_schema='test' and specific_name='myproc';
    -> end$$

mysql> call myproc(123, 456)$$
+---------+
| params  |
+---------+
| foo,bar |
+---------+
</code>```

You would need to use dynamic SQL to do this, but you can't reference stored proc parameters in dynamic SQL:

Demonstration:

```<code>mysql> create procedure myproc (in foo int, in bar int)
    -> begin
    -> set @sql = 'SELECT foo, bar';
    -> prepare stmt from @sql;
    -> execute stmt;
    -> end$$

mysql> call myproc(123, 456)$$
ERROR 1054 (42S22): Unknown column 'foo' in 'field list'
</code>```

I generally discourage people from using MySQL stored procedures. This task would be far easier in virtually any application programming language.

Body:
I am creating sort of auditing functionality for all of my stored procedures. I am able to fetch the name of the parameters that stored procedure has(from : information_schema.parameters table).
However, I would like to create generic code for all stored procedures that would fetch the name of the parameters and correspondingly get the value of those parameters for that invocation and log into another table.

e.g.

DELIMITER $$
CREATE DEFINER=`root`@`localhost` PROCEDURE `TestSP`(IN `name` VARCHAR(255), IN `userid` INT(255), IN `isnew` VARCHAR(11))
BEGIN

#DECLARE exit handler for sqlexception  ROLLBACK;
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
ROLLBACK;

INSERT INTO app_db_log(TYPE,MESSAGE, INFO) VALUES ('ERROR','An error has occurred, operation rollback and the stored procedure was terminated',<INSERT ALL THE PARAMETER VALUES AS SINGLE STRING HERE> );
COMMIT;

SELECT 'An error has occurred, operation rollback and the stored procedure was terminated';
END;

START TRANSACTION;
SIGNAL SQLSTATE '45000';
COMMIT;
END$$
DELIMITER ;

Thanks in advance!

Body:
You can get the list of parameters for the routine from INFORMATION_SCHEMA.PARAMETERS, but you'd have to know the schema and name of the procedure:

mysql> delimiter $$

mysql> create procedure myproc (in foo int, in bar int)
    -> begin
    -> select group_concat(parameter_name order by ordinal_position) as params
    -> from INFORMATION_SCHEMA.PARAMETERS
    -> where specific_schema='test' and specific_name='myproc';
    -> end$$

mysql> call myproc(123, 456)$$
+---------+
| params  |
+---------+
| foo,bar |
+---------+

You would need to use dynamic SQL to do this, but you can't reference stored proc parameters in dynamic SQL:

Demonstration:

mysql> create procedure myproc (in foo int, in bar int)
    -> begin
    -> set @sql = 'SELECT foo, bar';
    -> prepare stmt from @sql;
    -> execute stmt;
    -> end$$

mysql> call myproc(123, 456)$$
ERROR 1054 (42S22): Unknown column 'foo' in 'field list'

I generally discourage people from using MySQL stored procedures. This task would be far easier in virtually any application programming language.


问:
Single image launch screen implementation for cordova hybrid app
I have gone through splash doc https://github.com/apache/cordova-plugin-splashscreen#single-image-launch-screen
Here just using single image of 2732x2732px will show splashes on all devices.

In Android platform section, I have specified below line in config.xml

```<code><splash src="www/images/test.png" />
</code>```

I have also added preference for splashscreen

```<code><preference name="SplashScreen" value="screen" />
<preference name="AutoHideSplashScreen" value="true" />
<preference name="SplashMaintainAspectRatio" value="true" />
</code>```

But this is not working. App is getting crashed when I try to open the app . When I add all splashes with their densities it works as referred in https://stackoverflow.com/a/36045485/4677062.
Whereas documentation tells that this can be done using single image by just adding one splash to config and not for all the density images as specified in the above link.

答:
Those instructions for single image launch are for iOS not Android.

For Android you should use e.g.:

```<code>    <splash qualifier="land-hdpi" src="res/android/splash/landscape-hdpi.png" />
    <splash qualifier="land-ldpi" src="res/android/splash/landscape-ldpi.png" />
    <splash qualifier="land-mdpi" src="res/android/splash/landscape-mdpi.png" />
    <splash qualifier="land-xhdpi" src="res/android/splash/landscape-xhdpi.png" />
    <splash qualifier="port-hdpi" src="res/android/splash/portrait-hdpi.png" />
    <splash qualifier="port-ldpi" src="res/android/splash/portrait-ldpi.png" />
    <splash qualifier="port-mdpi" src="res/android/splash/portrait-mdpi.png" />
    <splash qualifier="port-xhdpi" src="res/android/splash/portrait-xhdpi.png" />
</code>```

Note: res/android/splash/ is my specific path, my custom build system copy files from this folder to www/images/

Body:
I have gone through splash doc https://github.com/apache/cordova-plugin-splashscreen#single-image-launch-screen
Here just using single image of 2732x2732px will show splashes on all devices.

In Android platform section, I have specified below line in config.xml

<splash src="www/images/test.png" />

I have also added preference for splashscreen

<preference name="SplashScreen" value="screen" />
<preference name="AutoHideSplashScreen" value="true" />
<preference name="SplashMaintainAspectRatio" value="true" />

But this is not working. App is getting crashed when I try to open the app . When I add all splashes with their densities it works as referred in https://stackoverflow.com/a/36045485/4677062.
Whereas documentation tells that this can be done using single image by just adding one splash to config and not for all the density images as specified in the above link.

Body:
Those instructions for single image launch are for iOS not Android.

For Android you should use e.g.:

    <splash qualifier="land-hdpi" src="res/android/splash/landscape-hdpi.png" />
    <splash qualifier="land-ldpi" src="res/android/splash/landscape-ldpi.png" />
    <splash qualifier="land-mdpi" src="res/android/splash/landscape-mdpi.png" />
    <splash qualifier="land-xhdpi" src="res/android/splash/landscape-xhdpi.png" />
    <splash qualifier="port-hdpi" src="res/android/splash/portrait-hdpi.png" />
    <splash qualifier="port-ldpi" src="res/android/splash/portrait-ldpi.png" />
    <splash qualifier="port-mdpi" src="res/android/splash/portrait-mdpi.png" />
    <splash qualifier="port-xhdpi" src="res/android/splash/portrait-xhdpi.png" />

Note: res/android/splash/ is my specific path, my custom build system copy files from this folder to www/images/


问:
HTML5 Video iOS play button disappearing
I have a simple HTML5 dash player instance created in jsfiddle..

https://jsfiddle.net/uumh8e6u/

```<code>  <video class="dashjs-player" poster="https://dummyimage.com/600x400/000/fff" autoplay playsinline>
                <source src="https://yt-dash-mse-test.commondatastorage.googleapis.com/media/car-20120827-manifest.mpd" type="application/dash+xml"/>
                <source src="https://bitdash-a.akamaihd.net/content/sintel/hls/playlist.m3u8" type="application/x-mpegURL">
            </video>
</code>```

When I try and play it on an iPad I get the poster image loading correctly and then the play button flashes on the screen for a second and then disappears.

Anybody any ideas why this is happening?

答:
Upadte:

The JSFiddle you supplied appears like it will not play on Safari on a MAC which sounds like a similar problem to the one you are observing.

However,if you right click on the poster and select show controls it shows the video and it looks like it has been playing.

Similarly, if you add 'controls' attribute to the video tag it will will then autoplay correctly the video.

Note, this may be a JSFiddle limitation rather than a Safari or iOS limitation, but either way it is a reproducible effect (Safari Version 11.0.1 (12604.3.5.1.1)).

  <video class="dashjs-player" poster="https://dummyimage.com/600x400/000/fff" autoplay playsinline controls>
                <source src="https://yt-dash-mse-test.commondatastorage.googleapis.com/media/car-20120827-manifest.mpd" type="application/dash+xml"/>
                <source src="https://bitdash-a.akamaihd.net/content/sintel/hls/playlist.m3u8" type="application/x-mpegURL">
            </video>
```

<p>Its also worth noting that webkit.org recommendation is to not assume any media will autoplay, as browsers often allow users set preferences in this area. Their recommendation is to check and if necessary add a button or some control to allow the user play the video:</p>

<pre class="lang-js prettyprint-override"><code>var promise = document.querySelector('video').play();

if (promise !== undefined) {
    promise.catch(error => {
        // Auto-play was prevented
        // Show a UI element to let the user manually start playback
    }).then(() => {
        // Auto-play started
    });
}
</code>```

Original answer

If you look at your browser console and debugger, check if it is using the DASH stream or the HLS stream. iOS devices prefer HLS but I'm not sure if they would override your listed order.

If it is using the HLS stream then this would likely explain your issue - the reference dash.js player will not play the m3u8 file you linked either on Safari on a Mac, but it will play the mpd file you linked to:

http://dashif.org/reference/players/javascript/1.3.0/samples/dash-if-reference-player/index.html

The HLS file itself seems fine, it will play in the BitMovin test player for example without issue on the same system, Safari on MAC:

https://bitmovin.com/hls-mpeg-dash-test-player/

Body:
I have a simple HTML5 dash player instance created in jsfiddle..

https://jsfiddle.net/uumh8e6u/

  <video class="dashjs-player" poster="https://dummyimage.com/600x400/000/fff" autoplay playsinline>
                <source src="https://yt-dash-mse-test.commondatastorage.googleapis.com/media/car-20120827-manifest.mpd" type="application/dash+xml"/>
                <source src="https://bitdash-a.akamaihd.net/content/sintel/hls/playlist.m3u8" type="application/x-mpegURL">
            </video>

When I try and play it on an iPad I get the poster image loading correctly and then the play button flashes on the screen for a second and then disappears.

Anybody any ideas why this is happening?

Body:
Upadte:

The JSFiddle you supplied appears like it will not play on Safari on a MAC which sounds like a similar problem to the one you are observing.

However,if you right click on the poster and select show controls it shows the video and it looks like it has been playing.

Similarly, if you add 'controls' attribute to the video tag it will will then autoplay correctly the video.

Note, this may be a JSFiddle limitation rather than a Safari or iOS limitation, but either way it is a reproducible effect (Safari Version 11.0.1 (12604.3.5.1.1)).

  <video class="dashjs-player" poster="https://dummyimage.com/600x400/000/fff" autoplay playsinline controls>
                <source src="https://yt-dash-mse-test.commondatastorage.googleapis.com/media/car-20120827-manifest.mpd" type="application/dash+xml"/>
                <source src="https://bitdash-a.akamaihd.net/content/sintel/hls/playlist.m3u8" type="application/x-mpegURL">
            </video>

Its also worth noting that webkit.org recommendation is to not assume any media will autoplay, as browsers often allow users set preferences in this area. Their recommendation is to check and if necessary add a button or some control to allow the user play the video:

var promise = document.querySelector('video').play();

if (promise !== undefined) {
    promise.catch(error => {
        // Auto-play was prevented
        // Show a UI element to let the user manually start playback
    }).then(() => {
        // Auto-play started
    });
}

Original answer

If you look at your browser console and debugger, check if it is using the DASH stream or the HLS stream. iOS devices prefer HLS but I'm not sure if they would override your listed order.

If it is using the HLS stream then this would likely explain your issue - the reference dash.js player will not play the m3u8 file you linked either on Safari on a Mac, but it will play the mpd file you linked to:

http://dashif.org/reference/players/javascript/1.3.0/samples/dash-if-reference-player/index.html

The HLS file itself seems fine, it will play in the BitMovin test player for example without issue on the same system, Safari on MAC:

https://bitmovin.com/hls-mpeg-dash-test-player/


问:
boost spirit parsing with no skipper
Think about a preprocessor which will read the raw text (no significant white space or tokens).

There are 3 rules.

resolve_para_entry should solve the Argument inside a call. The top-level text is returned as string.

resolve_para should resolve the whole Parameter list and put all the top-level Parameter in a string list.

resolve is the entry

On the way I track the iterator and get the text portion

Samples:

sometext(para)        → expect para in the string list

sometext(para1,para2) → expect para1 and para2 in string list

sometext(call(a))     → expect call(a) in the string list

sometext(call(a,b))   ← here it fails; it seams that the "!lit(',')" wont take the Parser to step outside ..

Rules:

```<code>resolve_para_entry = +(
     (iter_pos >> lit('(') >> (resolve_para_entry | eps) >> lit(')') >> iter_pos) [_val=  phoenix::bind(&appendString, _val, _1,_3)]
     | (!lit(',') >> !lit(')') >> !lit('(') >> (wide::char_ | wide::space))         [_val = phoenix::bind(&appendChar, _val, _1)]
    );

resolve_para = (lit('(') >> lit(')'))[_val = std::vector<std::wstring>()]  // empty para -> old style
    | (lit('(') >> resolve_para_entry >> *(lit(',') >> resolve_para_entry) > lit(')'))[_val = phoenix::bind(&appendStringList, _val, _1, _2)]
    | eps;
  ;

resolve = (iter_pos >> name_valid >> iter_pos >> resolve_para >> iter_pos);
</code>```

In the end doesn't seem very elegant. Maybe there is a better way to parse such stuff without skipper

答:
Indeed this should be a lot simpler.

First off, I fail to see why the absense of a skipper is at all relevant.

Second, exposing the raw input is best done using qi::raw[] instead of dancing with iter_pos and clumsy semantic actions¹.

Among the other observations I see:

negating a charset is done with ~, so e.g. ~char_(",()")

(p|eps) would be better spelled -p

(lit('(') >> lit(')')) could be just "()" (after all, there's no skipper, right)

p >> *(',' >> p) is equivalent to p % ','

With the above, resolve_para simplifies to this:

```<code>resolve_para = '(' >> -(resolve_para_entry % ',') >> ')';
</code>```

resolve_para_entry seems weird, to me. It appears that any nested parentheses are simply swallowed. Why not actually parse a recursive grammar so you detect syntax errors?

Here's my take on it:

Define An AST

I prefer to make this the first step because it helps me think about the parser productions:

```<code>namespace Ast {

    using ArgList = std::list<std::string>;

    struct Resolve {
        std::string name;
        ArgList arglist;
    };

    using Resolves = std::vector<Resolve>;
}
</code>```

Creating The Grammar Rules

```<code>qi::rule<It, Ast::Resolves()> start;
qi::rule<It, Ast::Resolve()>  resolve;
qi::rule<It, Ast::ArgList()>  arglist;
qi::rule<It, std::string()>   arg, identifier;
</code>```

And their definitions:

```<code>identifier = char_("a-zA-Z_") >> *char_("a-zA-Z0-9_");

arg        = raw [ +('(' >> -arg >> ')' | +~char_(",)(")) ];
arglist    = '(' >> -(arg % ',') >> ')';
resolve    = identifier >> arglist;

start      = *qr::seek[hold[resolve]];
</code>```

Notes:

No more semantic actions

No more eps

No more iter_pos

I've opted to make arglist not-optional. If you really wanted that, change it back:

```<code>resolve    = identifier >> -arglist;
</code>```

But in our sample it will generate a lot of noisy output.

Of course your entry point (start) will be different. I just did the simplest thing that could possibly work, using another handy parser directive from the Spirit Repository (like iter_pos that you were already using): seek[]

The hold is there for this reason: boost::spirit::qi duplicate parsing on the output - You might not need it in your actual parser.

Live On Coliru

```<code>#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/repository/include/qi_seek.hpp>

namespace Ast {

    using ArgList = std::list<std::string>;

    struct Resolve {
        std::string name;
        ArgList arglist;
    };

    using Resolves = std::vector<Resolve>;
}

BOOST_FUSION_ADAPT_STRUCT(Ast::Resolve, name, arglist)

namespace qi = boost::spirit::qi;
namespace qr = boost::spirit::repository::qi;

template <typename It>
struct Parser : qi::grammar<It, Ast::Resolves()>
{
    Parser() : Parser::base_type(start) {
        using namespace qi;

        identifier = char_("a-zA-Z_") >> *char_("a-zA-Z0-9_");

        arg        = raw [ +('(' >> -arg >> ')' | +~char_(",)(")) ];
        arglist    = '(' >> -(arg % ',') >> ')';
        resolve    = identifier >> arglist;

        start      = *qr::seek[hold[resolve]];
    }
  private:
    qi::rule<It, Ast::Resolves()> start;
    qi::rule<It, Ast::Resolve()>  resolve;
    qi::rule<It, Ast::ArgList()>  arglist;
    qi::rule<It, std::string()>   arg, identifier;
};

#include <iostream>

int main() {
    using It = std::string::const_iterator;
    std::string const samples = R"--(
Samples:

sometext(para)        → expect para in the string list
sometext(para1,para2) → expect para1 and para2 in string list
sometext(call(a))     → expect call(a) in the string list
sometext(call(a,b))   ← here it fails; it seams that the "!lit(',')" wont make the parser step outside
)--";
    It f = samples.begin(), l = samples.end();

    Ast::Resolves data;
    if (parse(f, l, Parser<It>{}, data)) {
        std::cout << "Parsed " << data.size() << " resolves\n";

    } else {
        std::cout << "Parsing failed\n";
    }

    for (auto& resolve: data) {
        std::cout << " - " << resolve.name << "\n   (\n";
        for (auto& arg : resolve.arglist) {
            std::cout << "       " << arg << "\n";
        }
        std::cout << "   )\n";
    }
}
</code>```

Prints

```<code>Parsed 6 resolves
 - sometext
   (
       para
   )
 - sometext
   (
       para1
       para2
   )
 - sometext
   (
       call(a)
   )
 - call
   (
       a
   )
 - call
   (
       a
       b
   )
 - lit
   (
       '
       '
   )
</code>```

More Ideas

That last output shows you a problem with your current grammar: lit(',') should obviously not be seen as a call with two parameters.

I recently did an answer on extracting (nested) function calls with parameters which does things more neatly:

Boost spirit parse rule is not applied

or this one boost spirit reporting semantic error

BONUS

Bonus version that uses string_view and also shows exact line/column information of all extracted words.

Note that it still doesn't require any phoenix or semantic actions. Instead it simply defines the necesary trait to assign to boost::string_view from an iterator range.

Live On Coliru

```<code>#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/repository/include/qi_seek.hpp>
#include <boost/utility/string_view.hpp>

namespace Ast {

    using Source  = boost::string_view;
    using ArgList = std::list<Source>;

    struct Resolve {
        Source name;
        ArgList arglist;
    };

    using Resolves = std::vector<Resolve>;
}

BOOST_FUSION_ADAPT_STRUCT(Ast::Resolve, name, arglist)

namespace boost { namespace spirit { namespace traits {
    template <typename It>
    struct assign_to_attribute_from_iterators<boost::string_view, It, void> {
        static void call(It f, It l, boost::string_view& attr) {
            attr = boost::string_view { f.base(), size_t(std::distance(f.base(),l.base())) };
        }
    };
} } }

namespace qi = boost::spirit::qi;
namespace qr = boost::spirit::repository::qi;

template <typename It>
struct Parser : qi::grammar<It, Ast::Resolves()>
{
    Parser() : Parser::base_type(start) {
        using namespace qi;

        identifier = raw [ char_("a-zA-Z_") >> *char_("a-zA-Z0-9_") ];

        arg        = raw [ +('(' >> -arg >> ')' | +~char_(",)(")) ];
        arglist    = '(' >> -(arg % ',') >> ')';
        resolve    = identifier >> arglist;

        start      = *qr::seek[hold[resolve]];
    }
  private:
    qi::rule<It, Ast::Resolves()> start;
    qi::rule<It, Ast::Resolve()>  resolve;
    qi::rule<It, Ast::ArgList()>  arglist;
    qi::rule<It, Ast::Source()>   arg, identifier;
};

#include <iostream>

struct Annotator {
    using Ref = boost::string_view;

    struct Manip {
        Ref fragment, context;

        friend std::ostream& operator<<(std::ostream& os, Manip const& m) {
            return os << "[" << m.fragment << " at line:" << m.line() << " col:" << m.column() << "]";
        }

        size_t line() const {
            return 1 + std::count(context.begin(), fragment.begin(), '\n');
        }
        size_t column() const {
            return 1 + (fragment.begin() - start_of_line().begin());
        }
        Ref start_of_line() const {
            return context.substr(context.substr(0, fragment.begin()-context.begin()).find_last_of('\n') + 1);
        }
    };

    Ref context;
    Manip operator()(Ref what) const { return {what, context}; }
};

int main() {
    using It = std::string::const_iterator;
    std::string const samples = R"--(Samples:

sometext(para)        → expect para in the string list
sometext(para1,para2) → expect para1 and para2 in string list
sometext(call(a))     → expect call(a) in the string list
sometext(call(a,b))   ← here it fails; it seams that the "!lit(',')" wont make the parser step outside
)--";
    It f = samples.begin(), l = samples.end();

    Ast::Resolves data;
    if (parse(f, l, Parser<It>{}, data)) {
        std::cout << "Parsed " << data.size() << " resolves\n";

    } else {
        std::cout << "Parsing failed\n";
    }

    Annotator annotate{samples};

    for (auto& resolve: data) {
        std::cout << " - " << annotate(resolve.name) << "\n   (\n";
        for (auto& arg : resolve.arglist) {
            std::cout << "       " << annotate(arg) << "\n";
        }
        std::cout << "   )\n";
    }
}
</code>```

Prints

```<code>Parsed 6 resolves
 - [sometext at line:3 col:1]
   (
       [para at line:3 col:10]
   )
 - [sometext at line:4 col:1]
   (
       [para1 at line:4 col:10]
       [para2 at line:4 col:16]
   )
 - [sometext at line:5 col:1]
   (
       [call(a) at line:5 col:10]
   )
 - [call at line:5 col:34]
   (
       [a at line:5 col:39]
   )
 - [call at line:6 col:10]
   (
       [a at line:6 col:15]
       [b at line:6 col:17]
   )
 - [lit at line:6 col:62]
   (
       [' at line:6 col:66]
       [' at line:6 col:68]
   )
</code>```

¹ Boost Spirit: "Semantic actions are evil"?

Title: boost spirit parsing with no skipper

Body:
Think about a preprocessor which will read the raw text (no significant white space or tokens).

There are 3 rules.

resolve_para_entry should solve the Argument inside a call. The top-level text is returned as string.

resolve_para should resolve the whole Parameter list and put all the top-level Parameter in a string list.

resolve is the entry

On the way I track the iterator and get the text portion

Samples:

sometext(para)        → expect para in the string list

sometext(para1,para2) → expect para1 and para2 in string list

sometext(call(a))     → expect call(a) in the string list

sometext(call(a,b))   ← here it fails; it seams that the "!lit(',')" wont take the Parser to step outside ..

Rules:

resolve_para_entry = +(
     (iter_pos >> lit('(') >> (resolve_para_entry | eps) >> lit(')') >> iter_pos) [_val=  phoenix::bind(&appendString, _val, _1,_3)]
     | (!lit(',') >> !lit(')') >> !lit('(') >> (wide::char_ | wide::space))         [_val = phoenix::bind(&appendChar, _val, _1)]
    );

resolve_para = (lit('(') >> lit(')'))[_val = std::vector<std::wstring>()]  // empty para -> old style
    | (lit('(') >> resolve_para_entry >> *(lit(',') >> resolve_para_entry) > lit(')'))[_val = phoenix::bind(&appendStringList, _val, _1, _2)]
    | eps;
  ;

resolve = (iter_pos >> name_valid >> iter_pos >> resolve_para >> iter_pos);

In the end doesn't seem very elegant. Maybe there is a better way to parse such stuff without skipper

Body:
Indeed this should be a lot simpler.

First off, I fail to see why the absense of a skipper is at all relevant.

Second, exposing the raw input is best done using qi::raw[] instead of dancing with iter_pos and clumsy semantic actions¹.

Among the other observations I see:

negating a charset is done with ~, so e.g. ~char_(",()")

(p|eps) would be better spelled -p

(lit('(') >> lit(')')) could be just "()" (after all, there's no skipper, right)

p >> *(',' >> p) is equivalent to p % ','

With the above, resolve_para simplifies to this:

resolve_para = '(' >> -(resolve_para_entry % ',') >> ')';

resolve_para_entry seems weird, to me. It appears that any nested parentheses are simply swallowed. Why not actually parse a recursive grammar so you detect syntax errors?

Here's my take on it:

Define An AST

I prefer to make this the first step because it helps me think about the parser productions:

namespace Ast {

    using ArgList = std::list<std::string>;

    struct Resolve {
        std::string name;
        ArgList arglist;
    };

    using Resolves = std::vector<Resolve>;
}

Creating The Grammar Rules

qi::rule<It, Ast::Resolves()> start;
qi::rule<It, Ast::Resolve()>  resolve;
qi::rule<It, Ast::ArgList()>  arglist;
qi::rule<It, std::string()>   arg, identifier;

And their definitions:

identifier = char_("a-zA-Z_") >> *char_("a-zA-Z0-9_");

arg        = raw [ +('(' >> -arg >> ')' | +~char_(",)(")) ];
arglist    = '(' >> -(arg % ',') >> ')';
resolve    = identifier >> arglist;

start      = *qr::seek[hold[resolve]];

Notes:

No more semantic actions

No more eps

No more iter_pos

I've opted to make arglist not-optional. If you really wanted that, change it back:

resolve    = identifier >> -arglist;

But in our sample it will generate a lot of noisy output.

Of course your entry point (start) will be different. I just did the simplest thing that could possibly work, using another handy parser directive from the Spirit Repository (like iter_pos that you were already using): seek[]

The hold is there for this reason: boost::spirit::qi duplicate parsing on the output - You might not need it in your actual parser.

Live On Coliru

#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/repository/include/qi_seek.hpp>

namespace Ast {

    using ArgList = std::list<std::string>;

    struct Resolve {
        std::string name;
        ArgList arglist;
    };

    using Resolves = std::vector<Resolve>;
}

BOOST_FUSION_ADAPT_STRUCT(Ast::Resolve, name, arglist)

namespace qi = boost::spirit::qi;
namespace qr = boost::spirit::repository::qi;

template <typename It>
struct Parser : qi::grammar<It, Ast::Resolves()>
{
    Parser() : Parser::base_type(start) {
        using namespace qi;

        identifier = char_("a-zA-Z_") >> *char_("a-zA-Z0-9_");

        arg        = raw [ +('(' >> -arg >> ')' | +~char_(",)(")) ];
        arglist    = '(' >> -(arg % ',') >> ')';
        resolve    = identifier >> arglist;

        start      = *qr::seek[hold[resolve]];
    }
  private:
    qi::rule<It, Ast::Resolves()> start;
    qi::rule<It, Ast::Resolve()>  resolve;
    qi::rule<It, Ast::ArgList()>  arglist;
    qi::rule<It, std::string()>   arg, identifier;
};

#include <iostream>

int main() {
    using It = std::string::const_iterator;
    std::string const samples = R"--(
Samples:

sometext(para)        → expect para in the string list
sometext(para1,para2) → expect para1 and para2 in string list
sometext(call(a))     → expect call(a) in the string list
sometext(call(a,b))   ← here it fails; it seams that the "!lit(',')" wont make the parser step outside
)--";
    It f = samples.begin(), l = samples.end();

    Ast::Resolves data;
    if (parse(f, l, Parser<It>{}, data)) {
        std::cout << "Parsed " << data.size() << " resolves\n";

    } else {
        std::cout << "Parsing failed\n";
    }

    for (auto& resolve: data) {
        std::cout << " - " << resolve.name << "\n   (\n";
        for (auto& arg : resolve.arglist) {
            std::cout << "       " << arg << "\n";
        }
        std::cout << "   )\n";
    }
}

Prints

Parsed 6 resolves
 - sometext
   (
       para
   )
 - sometext
   (
       para1
       para2
   )
 - sometext
   (
       call(a)
   )
 - call
   (
       a
   )
 - call
   (
       a
       b
   )
 - lit
   (
       '
       '
   )

More Ideas

That last output shows you a problem with your current grammar: lit(',') should obviously not be seen as a call with two parameters.

I recently did an answer on extracting (nested) function calls with parameters which does things more neatly:

Boost spirit parse rule is not applied

or this one boost spirit reporting semantic error

BONUS

Bonus version that uses string_view and also shows exact line/column information of all extracted words.

Note that it still doesn't require any phoenix or semantic actions. Instead it simply defines the necesary trait to assign to boost::string_view from an iterator range.

Live On Coliru

#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/repository/include/qi_seek.hpp>
#include <boost/utility/string_view.hpp>

namespace Ast {

    using Source  = boost::string_view;
    using ArgList = std::list<Source>;

    struct Resolve {
        Source name;
        ArgList arglist;
    };

    using Resolves = std::vector<Resolve>;
}

BOOST_FUSION_ADAPT_STRUCT(Ast::Resolve, name, arglist)

namespace boost { namespace spirit { namespace traits {
    template <typename It>
    struct assign_to_attribute_from_iterators<boost::string_view, It, void> {
        static void call(It f, It l, boost::string_view& attr) {
            attr = boost::string_view { f.base(), size_t(std::distance(f.base(),l.base())) };
        }
    };
} } }

namespace qi = boost::spirit::qi;
namespace qr = boost::spirit::repository::qi;

template <typename It>
struct Parser : qi::grammar<It, Ast::Resolves()>
{
    Parser() : Parser::base_type(start) {
        using namespace qi;

        identifier = raw [ char_("a-zA-Z_") >> *char_("a-zA-Z0-9_") ];

        arg        = raw [ +('(' >> -arg >> ')' | +~char_(",)(")) ];
        arglist    = '(' >> -(arg % ',') >> ')';
        resolve    = identifier >> arglist;

        start      = *qr::seek[hold[resolve]];
    }
  private:
    qi::rule<It, Ast::Resolves()> start;
    qi::rule<It, Ast::Resolve()>  resolve;
    qi::rule<It, Ast::ArgList()>  arglist;
    qi::rule<It, Ast::Source()>   arg, identifier;
};

#include <iostream>

struct Annotator {
    using Ref = boost::string_view;

    struct Manip {
        Ref fragment, context;

        friend std::ostream& operator<<(std::ostream& os, Manip const& m) {
            return os << "[" << m.fragment << " at line:" << m.line() << " col:" << m.column() << "]";
        }

        size_t line() const {
            return 1 + std::count(context.begin(), fragment.begin(), '\n');
        }
        size_t column() const {
            return 1 + (fragment.begin() - start_of_line().begin());
        }
        Ref start_of_line() const {
            return context.substr(context.substr(0, fragment.begin()-context.begin()).find_last_of('\n') + 1);
        }
    };

    Ref context;
    Manip operator()(Ref what) const { return {what, context}; }
};

int main() {
    using It = std::string::const_iterator;
    std::string const samples = R"--(Samples:

sometext(para)        → expect para in the string list
sometext(para1,para2) → expect para1 and para2 in string list
sometext(call(a))     → expect call(a) in the string list
sometext(call(a,b))   ← here it fails; it seams that the "!lit(',')" wont make the parser step outside
)--";
    It f = samples.begin(), l = samples.end();

    Ast::Resolves data;
    if (parse(f, l, Parser<It>{}, data)) {
        std::cout << "Parsed " << data.size() << " resolves\n";

    } else {
        std::cout << "Parsing failed\n";
    }

    Annotator annotate{samples};

    for (auto& resolve: data) {
        std::cout << " - " << annotate(resolve.name) << "\n   (\n";
        for (auto& arg : resolve.arglist) {
            std::cout << "       " << annotate(arg) << "\n";
        }
        std::cout << "   )\n";
    }
}

Prints

Parsed 6 resolves
 - [sometext at line:3 col:1]
   (
       [para at line:3 col:10]
   )
 - [sometext at line:4 col:1]
   (
       [para1 at line:4 col:10]
       [para2 at line:4 col:16]
   )
 - [sometext at line:5 col:1]
   (
       [call(a) at line:5 col:10]
   )
 - [call at line:5 col:34]
   (
       [a at line:5 col:39]
   )
 - [call at line:6 col:10]
   (
       [a at line:6 col:15]
       [b at line:6 col:17]
   )
 - [lit at line:6 col:62]
   (
       [' at line:6 col:66]
       [' at line:6 col:68]
   )

¹ Boost Spirit: "Semantic actions are evil"?


问:
How do I append a newline character for all lines except the last one?
I'm iterating through a HashMap (see my earlier question for more detail) and building a string consisting of the data contained in the Map.  For each item, I will have a new line, but for the very last item, I don't want the new line.  How can I achieve this? I was thinking I could so some kind of check to see if the entry is the last one or not, but I'm not sure how to actually do that.

Thanks!

答: This is where a join method, to complement split, would come in handy, because then you could just join all the elements using a new line as the separator, and of course it doesn't append a new line to the end of the result; that's how I do it in various scripting languages (Javascript, PHP, etc.).</p>

OwnerDisplayName: Blue

OwnerDisplayName: George Jempty

LastEditorDisplayName: George Jempty


问:
Type.GetFields() - only returning "public const" fields
I want to call Type.GetFields() and only get back fields declared as "public const".  I have this so far...

```<code>type.GetFields(BindingFlags.Static | BindingFlags.Public)
</code>```

... but that also includes "public static" fields.

答:
Starting from .NET 4.5 you can do that

```<code>public class ConstTest
{
    private const int ConstField = 123;

    public int GetValueOfConstViaReflection()
    {
        var fields = this.GetType().GetRuntimeFields();
        return (int)fields.First(f => f.Name == nameof(ConstField)).GetValue(null);
    }
}
</code>```

I checked and it looks like fields has all private consts.

Body:
I want to call Type.GetFields() and only get back fields declared as "public const".  I have this so far...

type.GetFields(BindingFlags.Static | BindingFlags.Public)

... but that also includes "public static" fields.

Body:
Starting from .NET 4.5 you can do that

public class ConstTest
{
    private const int ConstField = 123;

    public int GetValueOfConstViaReflection()
    {
        var fields = this.GetType().GetRuntimeFields();
        return (int)fields.First(f => f.Name == nameof(ConstField)).GetValue(null);
    }
}

I checked and it looks like fields has all private consts.


问:
Dilemma with Toast message
I'm developing a simple app, the user will have to fill in their name, email, rate the app, and describe their experience(optional). If their is an empty field(name and email), an error message will pop up. I'm having trouble with Toast.LENGTH_LONG() at the end of the code. It keep saying 'method call expected'.

MainActivity.java

```<code>@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    Spinner spinner = (Spinner) findViewById(R.id.spinner1);

    //Create an array adapter
    ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this, R.array.rate_array, android.R.layout.simple_spinner_dropdown_item);

    //Specify the layout for the drop down menu
    adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

    //Apply the adapter to the spinner
    spinner.setAdapter(adapter);

    final EditText name = (EditText) findViewById(R.id.Name);
    final EditText e_mail = (EditText) findViewById(R.id.email);
    final Button submit = (Button) findViewById(R.id.submit);

    submit.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if(name.getText().length() == 0){
                name.setError("Please fill in your name");
            }
            else{
                if(e_mail.getText().length() == 0){
                    e_mail.setError("Please fill in your email");
                }
                else{
                    Toast.makeText(this, "Validation successful",
                    Toast.LENGTH_LONG()).show();
                }
            }
        }
    });

 }
}
</code>```

activity_main.xml

```<code><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.infinite_space.myapplication.MainActivity"
android:orientation="vertical"
android:weightSum="1">

<TextView
    android:id="@+id/textView"
    android:layout_width="292dp"
    android:layout_height="37dp"
    android:text="Enter Feedback details to b sent to the developers"
    android:visibility="visible"
    tools:layout_editor_absoluteX="16dp"
    tools:layout_editor_absoluteY="16dp"
    android:layout_weight="0.18" />

<EditText
    android:id="@+id/Name"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:ems="10"
    android:hint="Your Name"
    android:inputType="textPersonName"
    tools:layout_editor_absoluteX="16dp"
    tools:layout_editor_absoluteY="67dp" />

<Spinner
    android:id="@+id/spinner1"
    android:layout_width="fill_parent"
    android:layout_height="35dp"
    android:background="@android:drawable/btn_dropdown"
    android:spinnerMode="dropdown"
    tools:layout_editor_absoluteY="176dp"
    tools:layout_editor_absoluteX="16dp"
    android:prompt="@string/rate_level"
    android:entries="@array/rate_array" />

<EditText
    android:id="@+id/email"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:ems="10"
    android:hint="Your email"
    android:inputType="textEmailAddress"
    tools:layout_editor_absoluteX="16dp"
    tools:layout_editor_absoluteY="122dp" />

<EditText
    android:id="@+id/details"
    android:layout_width="fill_parent"
    android:layout_height="103dp"
    android:ems="10"
    android:hint="Details..."
    android:inputType="text"
    tools:layout_editor_absoluteX="16dp"
    tools:layout_editor_absoluteY="227dp" />

<CheckBox
    android:id="@+id/checkBox"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Would you like an email respond ?"
    tools:layout_editor_absoluteX="0dp"
    tools:layout_editor_absoluteY="343dp" />

<Button
    android:id="@+id/submit"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="Send Feedback"
    tools:layout_editor_absoluteX="0dp"
    tools:layout_editor_absoluteY="385dp" />
</LinearLayout>
</code>```

答: Should be either LENGTH_LONG for a long period of time or LENGTH_SHORT for a short period of time. Get rid of the () after LENGTH_LONG.

Title: Dilemma with Toast message

Body:
I'm developing a simple app, the user will have to fill in their name, email, rate the app, and describe their experience(optional). If their is an empty field(name and email), an error message will pop up. I'm having trouble with Toast.LENGTH_LONG() at the end of the code. It keep saying 'method call expected'.

MainActivity.java

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    Spinner spinner = (Spinner) findViewById(R.id.spinner1);

    //Create an array adapter
    ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this, R.array.rate_array, android.R.layout.simple_spinner_dropdown_item);

    //Specify the layout for the drop down menu
    adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

    //Apply the adapter to the spinner
    spinner.setAdapter(adapter);

    final EditText name = (EditText) findViewById(R.id.Name);
    final EditText e_mail = (EditText) findViewById(R.id.email);
    final Button submit = (Button) findViewById(R.id.submit);

    submit.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if(name.getText().length() == 0){
                name.setError("Please fill in your name");
            }
            else{
                if(e_mail.getText().length() == 0){
                    e_mail.setError("Please fill in your email");
                }
                else{
                    Toast.makeText(this, "Validation successful",
                    Toast.LENGTH_LONG()).show();
                }
            }
        }
    });

 }
}

activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.infinite_space.myapplication.MainActivity"
android:orientation="vertical"
android:weightSum="1">

<TextView
    android:id="@+id/textView"
    android:layout_width="292dp"
    android:layout_height="37dp"
    android:text="Enter Feedback details to b sent to the developers"
    android:visibility="visible"
    tools:layout_editor_absoluteX="16dp"
    tools:layout_editor_absoluteY="16dp"
    android:layout_weight="0.18" />

<EditText
    android:id="@+id/Name"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:ems="10"
    android:hint="Your Name"
    android:inputType="textPersonName"
    tools:layout_editor_absoluteX="16dp"
    tools:layout_editor_absoluteY="67dp" />

<Spinner
    android:id="@+id/spinner1"
    android:layout_width="fill_parent"
    android:layout_height="35dp"
    android:background="@android:drawable/btn_dropdown"
    android:spinnerMode="dropdown"
    tools:layout_editor_absoluteY="176dp"
    tools:layout_editor_absoluteX="16dp"
    android:prompt="@string/rate_level"
    android:entries="@array/rate_array" />

<EditText
    android:id="@+id/email"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:ems="10"
    android:hint="Your email"
    android:inputType="textEmailAddress"
    tools:layout_editor_absoluteX="16dp"
    tools:layout_editor_absoluteY="122dp" />

<EditText
    android:id="@+id/details"
    android:layout_width="fill_parent"
    android:layout_height="103dp"
    android:ems="10"
    android:hint="Details..."
    android:inputType="text"
    tools:layout_editor_absoluteX="16dp"
    tools:layout_editor_absoluteY="227dp" />

<CheckBox
    android:id="@+id/checkBox"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Would you like an email respond ?"
    tools:layout_editor_absoluteX="0dp"
    tools:layout_editor_absoluteY="343dp" />

<Button
    android:id="@+id/submit"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="Send Feedback"
    tools:layout_editor_absoluteX="0dp"
    tools:layout_editor_absoluteY="385dp" />
</LinearLayout>


问:
Running pmd on code with StringBuilder gives error about initialized size and appended size
```<code>private static String buildSomeString(Map<String, String> data) {
    StringBuilder result = new StringBuilder();
    for (Map.Entry<String, String> field : data.entrySet()) {
       result.append("some literal")
            .append(field.getKey())
            .append("another literal")
            .append(field.getKey())
            .append("and another one")
            .append(field.getValue())
            .append("and the last in this iteration");
     }
     return result.toString();
}
</code>```

When I run pmd on this I get the following error

```<code>StringBuffer constructor is initialized with size 16, but has at least 83 characters appended.
</code>```

The number of characters is probably wrong, because I changed literals before posting.

Thanks

答:
When you create a StringBuilder with default capacity, it's internal array has to be extended if you append beyond that capacity.

If you know the length of the final String that you need to create then you can create a StringBuilder with that capacity, so it will know that you need that many characters, and it's internal array will not need to be extended.

Body:
private static String buildSomeString(Map<String, String> data) {
    StringBuilder result = new StringBuilder();
    for (Map.Entry<String, String> field : data.entrySet()) {
       result.append("some literal")
            .append(field.getKey())
            .append("another literal")
            .append(field.getKey())
            .append("and another one")
            .append(field.getValue())
            .append("and the last in this iteration");
     }
     return result.toString();
}

When I run pmd on this I get the following error

StringBuffer constructor is initialized with size 16, but has at least 83 characters appended.

The number of characters is probably wrong, because I changed literals before posting.

Thanks


问:
Curve fit with three points with a given slope
This might be of math problem than Matlab. Nonetheless, here is my problem.

so, I have a data set represented by the green curve.  It's usually linear, but sometimes it can have a slight curvature.  Then, I have two additional points: the red and the blue.  The red is far out in the negative.  Its amplitude is 30~100 bigger than the X value of the green circle and it's always on the X-axis.  The blue circle is always on the Y-axis.

I need a curve that fits the red, the blue, and the green circles, but there are two more constraints:

Blue curve can't be negative

where the blue curve meets the green curve, I want the slopes of them to be the same (smooth transition)

The red point doesn't have to be on the Y-axis, but asymptotic to zero and very close to zero at the red circle.

I have tried different inverse functions such as exponential, polynomial, 1/something, etc., but without a slope constraint, the end-result tends to have a cusp at the green point and it causes a problem for an overall analysis in which this curve-fitting function is used.

Can this be done?

答:
If you just need to roughly match the slope and you have access to the data points of the green curve (not just the green dot), you can use multiple points of the green curve in the fitting function together with the blue and red point. That should produce a curve that passes through all the points and pretty much match the slope in the green point.

Clearly, if you need to match the slope with mathematical precision, you need to set up another constraint equation as it was suggested by duffymo.


问:
How can I make a hidden panel toggle on focus or click?
I'm trying to make a panel that appears when focused or clicked. Originally it was on click only and it is easy to set it up that way, but for accessibility I needed to make it so it also expanded when someone tabbed to it (on focus). I tried making it so it opens on focus only since a click will focus as well, but then it wouldn't close when clicked on after open because the focus was still enabled. Anyone got an idea to how to make this work?

```<code>$('.online-banking a.button.toggleClosed').one("click focusin", function() {
    $(this).removeClass('toggleClosed');
    $(this).addClass('toggleOpen');
    $('.online-banking-slidedown').slideDown(function() {
        $('.online-banking-slidedown input[type="text"]').focus();
    });
});
$('.online-banking a.button.toggleOpen').one("click focusout", function() {
    $(this).removeClass('toggleOpen');
    $(this).addClass('toggleClosed');
    $('.online-banking-slidedown').slideUp(function() {
        $('.online-banking-slidedown input[type="text"]').blur();
    });
</code>```

and here's the HTML

```<code><div class="online-banking">
    <a href="#" class="button toggleClosed">Online <span>Banking</span> Login</a>
    <div class="online-banking-slidedown">
        <form id="login" name="login" method="post" action="login.aspx">
            <input type="radio" name="radio" value="radio" id="banking_personal" checked="checked">
            <label class="personal" for="banking_personal">Personal</label>
            <input type="radio" name="radio" value="radio" id="banking_business">
            <label class="business" for="banking_business">Business</label>
            <input name="LoginName" type="text" maxlength="25" autocomplete="off" placeholder="User ID">
            <input type="submit" value="Sign In" data-category="Login" data-action="Click" data-label="Button" data-value="">
        </form>
    </div>
</div>
</code>```

答:
Toggling implies more than one use. When you use .one() method that's all you get to do...once. Fix: Use .on()

If there's an opposite effect method, then there's probably a combination of both methods. Fix: toggleClass() and slideToggle() replaces the corresponding add/removeClass() and slideDown/Up() methods.

The .on() method can handle multiple events there's no need to make another event handler for focus and blur when the function is the same for all of them (i.e. toggling). Fix: Add click focus blur to the .on() method.

Added style=display:none to $('.online-banking-slidedown') which can be removed as long as .toggleClosed class has display:none in CSS.

Since the button is an nchor, it's a good precaution to add e.preventDefault() to keep the link from jumping to another location.

$('.online-banking a.button.toggleClosed').on("click focus blur", function(e) {
  e.preventDefault();
  e.stopImmediatePropagation();
  $(this).toggleClass('toggleClosed toggleOpen');
  $('.online-banking-slidedown').slideToggle();
});```
<pre class="snippet-code-html lang-html prettyprint-override"><code><script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="online-banking">
  Online <span>Banking</span> Login
  <div class="online-banking-slidedown" style='display:none'>
    <form id="login" name="login" method="post" action="login.aspx">
      <input type="radio" name="radio" value="radio" id="banking_personal" checked="checked">
      <label class="personal" for="banking_personal">Personal</label>
      <input type="radio" name="radio" value="radio" id="banking_business">
      <label class="business" for="banking_business">Business</label>
      <input name="LoginName" type="text" maxlength="25" autocomplete="off" placeholder="User ID">
      <input type="submit" value="Sign In" data-category="Login" data-action="Click" data-label="Button" data-value="">
    </form>
  </div>
</div></code>```

Body:
I'm trying to make a panel that appears when focused or clicked. Originally it was on click only and it is easy to set it up that way, but for accessibility I needed to make it so it also expanded when someone tabbed to it (on focus). I tried making it so it opens on focus only since a click will focus as well, but then it wouldn't close when clicked on after open because the focus was still enabled. Anyone got an idea to how to make this work?

$('.online-banking a.button.toggleClosed').one("click focusin", function() {
    $(this).removeClass('toggleClosed');
    $(this).addClass('toggleOpen');
    $('.online-banking-slidedown').slideDown(function() {
        $('.online-banking-slidedown input[type="text"]').focus();
    });
});
$('.online-banking a.button.toggleOpen').one("click focusout", function() {
    $(this).removeClass('toggleOpen');
    $(this).addClass('toggleClosed');
    $('.online-banking-slidedown').slideUp(function() {
        $('.online-banking-slidedown input[type="text"]').blur();
    });

and here's the HTML

    Online Banking Login

        <form id="login" name="login" method="post" action="login.aspx">
            <input type="radio" name="radio" value="radio" id="banking_personal" checked="checked">
            Personal
            <input type="radio" name="radio" value="radio" id="banking_business">
            Business
            <input name="LoginName" type="text" maxlength="25" autocomplete="off" placeholder="User ID">
            <input type="submit" value="Sign In" data-category="Login" data-action="Click" data-label="Button" data-value="">
        </form>

Body:
Toggling implies more than one use. When you use .one() method that's all you get to do...once. Fix: Use .on()

If there's an opposite effect method, then there's probably a combination of both methods. Fix: toggleClass() and slideToggle() replaces the corresponding add/removeClass() and slideDown/Up() methods.

The .on() method can handle multiple events there's no need to make another event handler for focus and blur when the function is the same for all of them (i.e. toggling). Fix: Add click focus blur to the .on() method.

Added style=display:none to $('.online-banking-slidedown') which can be removed as long as .toggleClosed class has display:none in CSS.

Since the button is an <a>nchor, it's a good precaution to add e.preventDefault() to keep the link from jumping to another location.

$('.online-banking a.button.toggleClosed').on("click focus blur", function(e) {
  e.preventDefault();
  e.stopImmediatePropagation();
  $(this).toggleClass('toggleClosed toggleOpen');
  $('.online-banking-slidedown').slideToggle();
});

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="online-banking">
  <a href="#" class="button toggleClosed">Online <span>Banking</span> Login</a>
  <div class="online-banking-slidedown" style='display:none'>
    <form id="login" name="login" method="post" action="login.aspx">
      <input type="radio" name="radio" value="radio" id="banking_personal" checked="checked">
      <label class="personal" for="banking_personal">Personal</label>
      <input type="radio" name="radio" value="radio" id="banking_business">
      <label class="business" for="banking_business">Business</label>
      <input name="LoginName" type="text" maxlength="25" autocomplete="off" placeholder="User ID">
      <input type="submit" value="Sign In" data-category="Login" data-action="Click" data-label="Button" data-value="">
    </form>
  </div>
</div>


问:
Python 2.7: check if default argument passed with a decorator
I am looking for something i'm not sure how to accompish and can't find an answer.

Lets say I have a function with unknown number of arguments except arg2. Also arg2 doesn't have a fixed argument location:

```<code>def some_func(arg1, arg2=None, maybe_arg3=None, maybe_not_arg4=None):
    # Do some stuff
</code>```

Now I want to check if arg2 has been passed by the user and replace it from a decorator, eg:

```<code>def some_dec(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        # Do some stuff
        # check if arg2 is passed and replace
        rv = func(*args, **kwargs)
        return rv
    return wrapper
</code>```

If it's passed as key/value then it's no problem to get it from kwargs BUT how do I get it if it's passed to args? (Since IDK the number of arguments the function requires)

答:
inspect.signature should give you what you want:

```<code>def f(x, y, z, a=4):
    pass

import inspect
s = inspect.signature(f)

b = s.bind_partial(2, 4, 6, 8)
'a' in b.arguments

-> True

b = s.bind_partial(2, 4, 6)
'a' in b.arguments

-> False
</code>```

Note that this was introduced at Python version 3.3. On older versions inspect.getargspec provides some of the same functionality.

So your decorator could look like:

```<code>import inspect
import functools

def nag_a(func):
    sig = inspect.signature(func)
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        if not 'a' in sig.bind_partial(*args, **kwargs).arguments:
            print("You really should pass 'a', y'know.")
        rv = func(*args, **kwargs)
        return rv
    return wrapper

def nag_a_27(func):
    spec = inspect.getargspec(func)
    psn = spec.args.index('a')
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        if not 'a' in kwargs and len(args) <= psn:
            print "You really should pass 'a', y'know."
        rv = func(*args, **kwargs)
        return rv
    return wrapper

@nag_a
def f(x, y, a=None):
    pass
</code>```

Body:
I am looking for something i'm not sure how to accompish and can't find an answer.

Lets say I have a function with unknown number of arguments except arg2. Also arg2 doesn't have a fixed argument location:

def some_func(arg1, arg2=None, maybe_arg3=None, maybe_not_arg4=None):
    # Do some stuff

Now I want to check if arg2 has been passed by the user and replace it from a decorator, eg:

def some_dec(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        # Do some stuff
        # check if arg2 is passed and replace
        rv = func(*args, **kwargs)
        return rv
    return wrapper

If it's passed as key/value then it's no problem to get it from kwargs BUT how do I get it if it's passed to args? (Since IDK the number of arguments the function requires)

Body:
inspect.signature should give you what you want:

def f(x, y, z, a=4):
    pass

import inspect
s = inspect.signature(f)

b = s.bind_partial(2, 4, 6, 8)
'a' in b.arguments

-> True

b = s.bind_partial(2, 4, 6)
'a' in b.arguments

-> False

Note that this was introduced at Python version 3.3. On older versions inspect.getargspec provides some of the same functionality.

So your decorator could look like:

import inspect
import functools

def nag_a(func):
    sig = inspect.signature(func)
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        if not 'a' in sig.bind_partial(*args, **kwargs).arguments:
            print("You really should pass 'a', y'know.")
        rv = func(*args, **kwargs)
        return rv
    return wrapper

def nag_a_27(func):
    spec = inspect.getargspec(func)
    psn = spec.args.index('a')
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        if not 'a' in kwargs and len(args) <= psn:
            print "You really should pass 'a', y'know."
        rv = func(*args, **kwargs)
        return rv
    return wrapper

@nag_a
def f(x, y, a=None):
    pass


问:
Collect jbpm error that occur in a workflow
How can errors(ex. if a scriptTask fails) be collected from jbpm and send to an external system (ex. kafka)?</p>

答:
In jBPM 7.1 new approach to error handling was introduced.
You can find more details in this blog post

I have not tested this: but you can try to implement your own version of ExcecutionErrorStorage, which will be responsible for storing messages in Kafka.

You can take a look at org.jbpm.runtime.manager.impl.error.DefaultExecutionErrorStorage for reference, in there DB is used as Error Storage.


问:
Java generics - Map of (typed) maps
I'm working on a (simple) caching solution of sorts, where a service can request a Cache object from a Map of caches. A Cache object works essentially just like a Map, too, with a key and a value and methods to access and store objects.

I came up with the following solution, but as you can see, it contains a cast (because get() can't know what the types of the nested object are supposed to be).

```<code>private final  Map<String, Cache<?, ?>> caches = new HashMap<String, Cache<?, ?>>();

public <K, V> Cache<K, V> getOrCreateCache(String identifier) {
    if (caches.containsKey(identifier)) {
        return (Cache<K, V>) caches.get(identifier);
    } else {
        Cache<K, V> cache = new CacheImpl<K, V>();
        caches.put(identifier, cache);
        return cache;
    }
}

private void test() {
    Cache<String, String> strCache = getOrCreateCache("string cache");
    strCache.set("key", "value");
}
</code>```

Now, my questions:

Is this a 'safe' approach, as long as classcastexceptions are handled properly? (probably going to catch those and pack them into a custom exception class)

Is there a 'safe' alternative? One with generics, if at all possible, because I like them and dislike casts.

(not directly related) Is this threadsafe? I assume not, but then, I'm no threading expert. Is it enough to just make the whole method synchronized, or would that (with half a dozen clients) cause too much overhead / locking? Is there a neat solution for that?

Edit: Woo, lots of answers, thanks! Editing here to describe an oddity I found while actually testing this:

```<code>    Cache<String, String> someCache = service.getOrCreateCache(cacheIdentifier);
    someCache.set("asdf", "sdfa");
    Cache<String, Integer> someCacheRetrievedAgain = service.getOrCreateCache(cacheIdentifier);
    System.out.println(someCacheRetrievedAgain.get("asdf")); // prints "sdfa". No errors whatsoever. Odd.
</code>```

答:
Is this a 'safe' approach, as long
      as classcastexceptions are handled
      properly? (probably going to catch
      those and pack them into a custom
      exception class)

Actually, the safest way to handle that would be to create the cache key using the key and value types. Something like this:

```<code>public String getCacheKey(Class<?> keyType, Class<?> valueType, String uniqueId){
    return keyType.getName()+"-"+valueType.getName()+"-"+uniqueId;
}
</code>```

That way you'd be sure that a cache is of the specified type.

Is there a 'safe' alternative? One
      with generics, if at all possible,
      because I like them and dislike
      casts.

Basically: if you don't like unchecked casting, you will have to supply implementation types to all methods.

(not directly related) Is this
      threadsafe? I assume not, but then,
      I'm no threading expert. Is it
      enough to just make the whole method
      synchronized, or would that (with
      half a dozen clients) cause too much
      overhead / locking? Is there a neat
      solution for that?

Synchronizing the method is awful. Use a ConcurrentHashMap and it's putIfAbsent() method

Title: Java generics - Map of (typed) maps

Body:
I'm working on a (simple) caching solution of sorts, where a service can request a Cache object from a Map of caches. A Cache object works essentially just like a Map, too, with a key and a value and methods to access and store objects.

I came up with the following solution, but as you can see, it contains a cast (because get() can't know what the types of the nested object are supposed to be).

private final  Map<String, Cache<?, ?>> caches = new HashMap<String, Cache<?, ?>>();

public <K, V> Cache<K, V> getOrCreateCache(String identifier) {
    if (caches.containsKey(identifier)) {
        return (Cache<K, V>) caches.get(identifier);
    } else {
        Cache<K, V> cache = new CacheImpl<K, V>();
        caches.put(identifier, cache);
        return cache;
    }
}

private void test() {
    Cache<String, String> strCache = getOrCreateCache("string cache");
    strCache.set("key", "value");
}

Now, my questions:

Is this a 'safe' approach, as long as classcastexceptions are handled properly? (probably going to catch those and pack them into a custom exception class)

Is there a 'safe' alternative? One with generics, if at all possible, because I like them and dislike casts.

(not directly related) Is this threadsafe? I assume not, but then, I'm no threading expert. Is it enough to just make the whole method synchronized, or would that (with half a dozen clients) cause too much overhead / locking? Is there a neat solution for that?

Edit: Woo, lots of answers, thanks! Editing here to describe an oddity I found while actually testing this:

    Cache<String, String> someCache = service.getOrCreateCache(cacheIdentifier);
    someCache.set("asdf", "sdfa");
    Cache<String, Integer> someCacheRetrievedAgain = service.getOrCreateCache(cacheIdentifier);
    System.out.println(someCacheRetrievedAgain.get("asdf")); // prints "sdfa". No errors whatsoever. Odd.

Body:
Is this a 'safe' approach, as long
      as classcastexceptions are handled
      properly? (probably going to catch
      those and pack them into a custom
      exception class)

Actually, the safest way to handle that would be to create the cache key using the key and value types. Something like this:

public String getCacheKey(Class<?> keyType, Class<?> valueType, String uniqueId){
    return keyType.getName()+"-"+valueType.getName()+"-"+uniqueId;
}

That way you'd be sure that a cache is of the specified type.

Is there a 'safe' alternative? One
      with generics, if at all possible,
      because I like them and dislike
      casts.

Basically: if you don't like unchecked casting, you will have to supply implementation types to all methods.

(not directly related) Is this
      threadsafe? I assume not, but then,
      I'm no threading expert. Is it
      enough to just make the whole method
      synchronized, or would that (with
      half a dozen clients) cause too much
      overhead / locking? Is there a neat
      solution for that?

Synchronizing the method is awful. Use a ConcurrentHashMap and it's putIfAbsent() method


问:
clipsToBounds seeming to have no effect in UIStackView
Is it possible to have a subview render outside a UIStackView? I have a vertical stack view with a button and a label, and I'm using the width of the stack view to set the button's height and width appropriately:

```<code>addArrangedSubview(self.loginMethodButton)
let widthConstraint = NSLayoutConstraint(item: self.loginMethodButton, attribute: .width, relatedBy: .equal, toItem: self, attribute: .width, multiplier: 1.0, constant: 0.0)
let heightConstraint = NSLayoutConstraint(item: self.loginMethodButton, attribute: .height, relatedBy: .equal, toItem: self.loginMethodButton, attribute: .width, multiplier: 1.0, constant: 0.0)
NSLayoutConstraint.activate([widthConstraint, heightConstraint])
</code>```

I then adjust the width in my viewController to appropriate sizes based on the situation. The problem is, in one of the smaller sizes the button needs to be, the width is smaller than the label beneath it, which cuts off the label.

If I call sizeToFit() when setting the label, it works, however, calling sizeToFit() when adjusting the sizes after the label has been set still results in the label being cut off. Setting clipsToBounds to false on both the label and stack view have no effect.

Is it possible to render a view outside of a stack view at all? Or am I going to have to find a way to re-work my constraints in order to fix this issue?

答:
UIStackView is a "non-rendering" object... all it does is arrange other views.

If the problem is that your UILabel is too wide to fit in the area made available by your Stack View, then you either need to set the label to "auto-shrink" the font, or you need to alter your Stack View constraints to allow for the wider label.

Edit Based on your other comment, the following was incorrect.

You need to set .clipsToBounds on the "containing" view... based on the graphic you are showing, that would be the darker-blue box (I'm assuming that is a UIView with the image and label as subviews).

Body:
Is it possible to have a subview render outside a UIStackView? I have a vertical stack view with a button and a label, and I'm using the width of the stack view to set the button's height and width appropriately:

addArrangedSubview(self.loginMethodButton)
let widthConstraint = NSLayoutConstraint(item: self.loginMethodButton, attribute: .width, relatedBy: .equal, toItem: self, attribute: .width, multiplier: 1.0, constant: 0.0)
let heightConstraint = NSLayoutConstraint(item: self.loginMethodButton, attribute: .height, relatedBy: .equal, toItem: self.loginMethodButton, attribute: .width, multiplier: 1.0, constant: 0.0)
NSLayoutConstraint.activate([widthConstraint, heightConstraint])

I then adjust the width in my viewController to appropriate sizes based on the situation. The problem is, in one of the smaller sizes the button needs to be, the width is smaller than the label beneath it, which cuts off the label.

If I call sizeToFit() when setting the label, it works, however, calling sizeToFit() when adjusting the sizes after the label has been set still results in the label being cut off. Setting clipsToBounds to false on both the label and stack view have no effect.

Is it possible to render a view outside of a stack view at all? Or am I going to have to find a way to re-work my constraints in order to fix this issue?